В прошлой статье я рассказывал о том, как изменить интерфейс 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
Комментариев нет:
Отправить комментарий