Оповещение пользователя: Toast

Начинаю цикл статей о способах оповещения пользователя. Цикл рассчитан на новичков. Существует три способа оповещения пользователя: через Toast, через Notification и через различные виды Dialog. Сегодня я расскажу об использовании первого типа оповещения — Toast.

Введение

Toast представляет собой всплывающее сообщение, которое позволяет быстро оповестить пользователя о произошедшем событии, например, сохранении настроек программы на SD-карте. Особенность Toast заключается в том, что во время появления сообщения пользователь может взаимодействовать с находящимися за ним Activity, либо с домашним экраном (home screen). Также стоит заметить, что пользователь не может контролировать закрытие Toast с помощью аппаратной кнопки Back или другими возможными способами, сообщение плавно появляется и потом само же плавно исчезает. Время задержки между появлением и исчезновением можно задавать программно. В большинстве случаев Toast представляет собой короткое сообщение, но присутствует возможность задать произвольный внешний вид Toast, например, добавить изображение рядом с текстом. Помимо этого можно управлять расположением Toast на экране. Toast может быть создан из Activity, либо из Service. В случае создания из сервиса Toast появляется поверх Activity, которое имеет фокус, либо поверх домашнего экрана.

Создание простого Toast

Создать простой Toast можно через статичный метод makeText класса Toast, задав необходимые параметры.
Toast.makeText(getApplicationContext()"Привет, мир!", Toast.LENGTH_SHORT).show();

В качестве параметров задается контекст приложения, сообщение и задержка, о которой писал ранее. Сообщение может быть задано непосредственно в виде текста, либо используя текстовый ресурс-строку, например, R.string.hello_world, в которой хранится текст, который необходимо отобразить, в нашем случае «Привет, мир!». Задержка может быть короткой — LENGTH_SHORT, либо длинной — LENGTH_LONG. По умолчанию при создании Toast задается короткая задержка. Программно задержка задается методом setDuration.

Суть метода makeText такова: внутри метода создается объект класса Toast, устанавливается текст сообщения и тип задержки. Далее к объекту может быть либо применен, как в моем случае, метод show, который отображает созданный Toast, либо заданы дополнительные свойства Toast, например, его расположение на экране или созданный вами внешний вид.

Созданный Toast выглядит следующим образом:

image

Изменение положения Toast

Расположение Toast на экране задается с помощью метода setGravity следующим образом:
Toast toast = Toast.makeText(getApplicationContext()"Привет, мир!",
Toast.LENGTH_LONG);toast.setGravity(Gravity.CENTER00);
toast.show();

Первый параметр метода задает выравнивание, вариантов которого довольно много в классе Gravity. Второй и третий параметры задают на сколько пикселей будет смещен Toast по горизонтали вправо и по вертикали вниз соответственно относительно значения, заданного в первом параметре. Результат приведенного выше кода отображается следующим образом:

image

Добавление изображения в простой Toast

Для добавления изображения в стандартный Toast потребуется программно создать объект класса ImageView и задать для него изображение из ресурсов с помощью метода setImageResource. Затем потребуется получить стандартный внешний вид Toast, если посмотреть в отладчике он является LinearLayout, и добавить в него созданный объект ImageView с указанием в какую позицию добавить изображение, в моем случае я указал нулевую позицию, чтобы изображение было добавлено выше текста. Код для создания этого Toast с изображением представлен ниже.
Toast toast = Toast.makeText(getApplicationContext()"Привет, мир!", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER00);
LinearLayout toastView = (LinearLayout) toast.getView();
ImageView imageWorld = new ImageView(getApplicationContext());
imageWorld.setImageResource(R.drawable.world);
toastView.addView(imageWorld, 0);
toast.show();

Созданный таким образом Toast выглядит следующим образом:

image

Создание сложного Toast

Для создания сложного Toast потребуется создать собственный layout, код которого выглядит следующим образом:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="schemas.android.com/apk/res/android"
 android:layout_height="wrap_content" android:layout_width="wrap_content"
 android:background="#ffffffff" android:orientation="vertical"
 android:id="@+id/llToast">
<TextView android:layout_height="wrap_content"
  android:layout_margin="1dip" android:textColor="#ffffffff"
  android:layout_width="fill_parent" android:gravity="center"
  android:background="#bb000000" android:id="@+id/tvTitleToast"></TextView>
<LinearLayout android:layout_height="wrap_content"
  android:orientation="vertical" android:id="@+id/llToastContent"
  android:layout_marginLeft="1dip" android:layout_marginRight="1dip"
  android:layout_marginBottom="1dip" android:layout_width="wrap_content"
  android:padding="15dip" android:background="#44000000">
<ImageView android:layout_height="wrap_content"
   android:layout_gravity="center" android:layout_width="wrap_content"
   android:id="@+id/tvImageToast" />
<TextView android:layout_height="wrap_content"
   android:paddingRight="10dip" android:paddingLeft="10dip"
   android:layout_width="wrap_content" android:gravity="center"
   android:textColor="#ff000000" android:id="@+id/tvTextToast" />
</LinearLayout>
</LinearLayout>

Я создал Toast в виде диалога с заголовком, внутри которого располагаются изображение и текст.

Теперь этот layout нужно прописать для Toast и задать сообщения для заголовка и текста, а также задать изображение. Делается это следующим образом:
LayoutInflater inflater = getLayoutInflater();
View layout = inflater.inflate(R.layout.toast,
  (ViewGroup) findViewById(R.id.llToast));
ImageView image = (ImageView) layout.findViewById(R.id.tvImageToast);
image.setImageResource(R.drawable.world);
TextView title = (TextView) layout.findViewById(R.id.tvTitleToast);
title.setText("Внимание");
TextView text = (TextView) layout.findViewById(R.id.tvTextToast);
text.setText("Привет, мир!");
 
Toast toast = new Toast(getApplicationContext());
toast.setGravity(Gravity.RIGHT | Gravity.TOP1240);
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(layout);
toast.show();

В первых двух строках происходит инициализация объекта View путем наполнения его из xml-файла (для этого используется экземпляр класса LayoutInflater, получаемый с помощью метода getLayoutInflater), созданного ранее. Первый параметр метода inflate задает идентификатор созданного ранее layout — R.layout.toast (в данном случае он соответствует файлу res/layout/toast.xml). Затем получаются ссылки на изображение, заголовок и текст сообщения, и заполняются нужными данными. Далее непосредственно создается Toast, задаются необходимые параметры и в качестве layout прописывается тот layout, который мы инициализировали ранее Делается это с помощью метода setView. В результате всех этих манипуляций у нас получится Toast, выглядящий как на рисунке ниже.

image

На этом первая статья о способах оповещения пользователя закончена. Если вы нашли ошибку или хотите добавить какие-то другие способы работы с Toast, напишите комментарии и я обязательно добавлю ваши замечания в статью.

Источник
+49
24 февраля 2010, 21:23
63
tum0rc0re 36,5

комментарии (14)

+1
Codebaker #
Отличная статья! Подскажите, о чем-то кроме оповещений в дальнейшем писать планируете?
0
tum0rc0re #
Вторая статья будет о Notification, попробую рассмотреть все ситуации, которые у меня возникли за весь опыт работы с платформой. Дальше будет статья о диалогах, помимо этого одновременно будет писаться статьи об использовании настроек в программе, как собственных, так и предоставляемых платформой.
+1
djvu #
Поделюсь своим опытом общения с Toast.
В процессе использования, выяснилось что эти уведомления не появлялись будучи вызванными из отдельного потока.
Пришлось в классе сервиса, который создает и запускает поток, объявить объект Handler переопределить в нем метод handleMessage:
final Handler alertHandler = new Handler() {
@Override
public void handleMessage(Message message) {
Bundle b = message.getData();
String text = b.getString(«MessageText»);
Toast.makeText(CurrentService.this, text, Toast.LENGTH_SHORT).show();
}
};
Дальше в сервисе определил новый метод
public void showToastMessage(String message) {
Message msg = new Message();
Bundle b = new Bundle();
b.putString(«MessageText», message);
msg.setData(b);
alertHandler.sendMessage(msg);
}
и уже его использовал для отсылки сообщений «наверх» из потока
0
tum0rc0re #
да именно так я и использую в своих проектах Toast, просто посчитал, что это не относится напрямую к ним, потому что когда в потоке работаешь в любом случае, чтобы обращаться к элементам нужно использовать Handler, либо метод post у различных типов View, если работаешь с TextView, ImageView и т.д.
0
jeck_landin #
Можно еще кстати с помощью android.os.Looper использовать UI из своего потока.
0
tum0rc0re #
да об этом слышал, но использовать не доводилось.
0
pixxxel #
Как раз вчера писал свое первое приложение (виджет) под андроид, оказалось что виджет, еще и с несколькими кнопками на нем сделать не очень тривиально. Надеюсь вы напишите про архитектуру виджетов, так как сам я не до конца понял суть.
Кстати, первой статьей было бы логичней написать о том чта такое activity, layout и тд.
0
pixxxel #
Извините, как-то я провтыкал ваши первые статьи. Про activity было уже, да. Спасибо) Вот только большинство статей ваших ссылаются на несуществующий сайт, а так хочется почитать. На русском очень мало о разработке под андроид
0
tum0rc0re #
да было, но они старые — со старого блога, я планирую их немного скорректировать вскоре и выложить уже с учетом 2.1 специфики, если там что-то изменится
0
tum0rc0re #
Кстати, некоторые мои статьи есть на androidforums.ru в разделе Статьи, но там не все, что были на старом блоге.
+1
tum0rc0re #
Насчет виджетов может и напишу попозже, потому что опыт создания довольно велик, если посмотрите на наши виджеты от CurveFish.
0
UdarEC #
Очень актуальная тема, спасибо Вам.
0
tum0rc0re #
не за что, может есть какие то пожелания по будущим статьям, можно что-то хочется узнать быстрей всего?
0
Halt #
Скажите пожалуйста, а виджеты по виду напоминающие тосты, но с кнопками и прочими контролами это что? Это тот же тост, но со сложным лейаутом (соответственно) или что-то еще?

Насколько я понимаю, тост прячется сам через некоторое время, как тултип. А в случае контролов его надо показывать, пока пользователь не среагирует.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.