В прошлой статье я рассказывал о том, как изменить интерфейс Toast и регулировать
время отображения его на экране. Сегодня я расскажу, как закрывать Toast по нажатию.
Практика
К сожалению, отследить клик у самого элемента Toast никак не получится, так
как он не активен для пользовательского взаимодействия. Мы прибегнем к
хитрости, и вместо Toast будем использовать PopupWindow. Это всплывающее окно можно кастомизировать так же
как Toast, но в отличие
от него, PopupWindow
может отлавливать пользовательские нажатия.
PopupWindow имеет несколько вариантов отображения:
- showAtLocation(View parent, int gravity, int x, int y): отображается в указанных координатах.
- showAsDropDown(View anchor): отображается как выпадающий список в левом нижнем углу заданного View.
- showAsDropDown(View anchor, int xoff, int yoff): отображается как выпадающий список в левом нижнем углу заданного View со смещением в велечину указанных координат.
В качестве рабочего проекта будем использовать проект,
созданный в предыдущей статье.
Изменим класс CustomToast для работы с PopupMenu.
Добавим статический атрибут, который указывает: отображается
или нет PopupWindow.
private static boolean isShow = false;
Также добавим Listener при срабатывании которого
происходит закрытие PopupWIndow.
private static OnClickListener listner = new OnClickListener() {
@Override
public void onClick(View v) {
isShow = false;
}
};
Изменим методы makeToast. Для PopupWindow необходим View,
относительного которого он будет отображаться.
public static void makeToast(Context context, View contentView, String msg, long duration) {
if (isShow)
return;
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.layout_toast, null);
view.setOnClickListener(listner);
((TextView) view.findViewById(R.id.text)).setText(msg);
showToast(context, contentView, view, duration);
}
public static void makeToast(Context context, View contentView, int msg, long duration) {
if (isShow)
return;
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.layout_toast, null);
((TextView) view.findViewById(R.id.text)).setText(msg);
view.setOnClickListener(listner);
showToast(context, contentView, view, duration);
}
Полностью изменим метод showToast, который будет создавать
наш PopupWindow. Чтобы наше всплывающее окно растягивалась по ширине на всю
область окна, а по высоте подстраивалось под TextView, используем константы ViewGroup.LayoutParams.MATCH_PARENT и ViewGroup.LayoutParams.WRAP_CONTENT.
private static void showToast(Context context, View contentView, View view, long duration) {
PopupWindow window = new PopupWindow(view, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, false);
show(context, contentView, duration * 1000, window);
}
Изменем метод для
отображения PopupWindow. Чтобы отобразить всплывающее окно в нижней части
экрана используется константа Gravity.BOTTOM.
private static void show(Context context, final View contentView, final long durationInMilliseconds,
final PopupWindow window) {
window.showAtLocation(contentView, Gravity.BOTTOM, 0, 0);
Thread t = new Thread() {
long timeElapsed = 0l;
public void run() {
try {
isShow = true;
while (timeElapsed <= durationInMilliseconds && isShow) {
long start = System.currentTimeMillis();
sleep(250);
timeElapsed += System.currentTimeMillis() - start;
}
isShow = false;
window.dismiss();
} catch (InterruptedException e) {
}
}
};
t.start();
}
Теперь немного изменим макет для основного окна. Добавим
идентификатор для главного Layout
окна, чтобы PopupWindow
отображался относительного него.
Исходный код (main.xml)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toast_layout_root"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/toast"
android:orientation="horizontal"
android:padding="8dp" >
<TextView
android:id="@+id/text"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginBottom="5dp"
android:gravity="center"
android:padding="8dp"
android:textColor="#FFF"
android:textSize="14sp" />
</LinearLayout>
Исходный код основного Activity с изменениями.
private EditText ed_txt, ed_time;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ed_time = (EditText)findViewById(R.id.ed_time);
ed_txt = (EditText)findViewById(R.id.ed_txt);
final Context context = this;
final View contentView = findViewById(R.id.main);
findViewById(R.id.btn_show).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int duration = 1;
try
{
duration = Integer.parseInt(ed_time.getText().toString());
} catch (Exception e) {
}
CustomToast.makeToast(context, contentView, ed_txt.getText().toString(), duration);
}
});
}
Ссылки
- Исходные коды данного проекта можно скачать отсюда: zip
Комментариев нет:
Отправить комментарий