Toast: 用户通知






4.83/5 (38投票s)
如何创建不同的 Toasts。
引言
Toast
是一种弹出消息,允许你快速通知用户某些事件。例如,将设置保存到 SD 卡。
Toast
的一个显著特点是,当消息仍然显示时,用户可以与它后面的 Activity 或主屏幕进行交互。同样值得注意的是,用户不能使用硬件“返回”键或其他方法来关闭 Toast
。消息会平滑地淡入,然后平滑地淡出。这些淡入淡出之间的时间间隔可以通过编程来设置。在大多数情况下,Toast
只是一个简短的消息,但你也可以为它创建一个自定义视图。例如,文本旁边的图像。Toast
在屏幕上的位置也可以控制。Toast
可以从 Activity 或 Service 创建。如果从 Service 创建 Toast,它会显示在当前具有焦点的 Activity 前面,或主屏幕的顶部。
创建标准 Toast
可以通过调用 Toast
类的 static makeText
方法来创建一个标准 Toast
。
Toast.makeText(getApplicationContext(), "Hello, The Code Project!",
Toast.LENGTH_SHORT).show();
应用程序上下文、消息本身和 Toast
的持续时间作为参数传递。你可以将消息文本设置为文本或存储要显示的 string
的资源。在我们的例子中,R.string.hello_codeproject
资源包含“Hello, The Code Project!
”字符串。持续时间可以是短的 - LENGTH_SHORT
或长的 - LENGTH_LONG
。默认情况下,持续时间设置为短。你可以通过调用 setDuration
方法以编程方式设置持续时间。
makeText
方法背后的逻辑非常简单:创建一个 Toast
对象,然后设置消息文本和持续时间。之后,你可以调用 show
方法来显示新创建的 Toast
,或者设置一些其他属性,例如它在屏幕上的位置或 Toast
的自定义视图。新创建的 Toast
如下图所示

设置 Toast 在屏幕上的位置
你可以通过调用 setGravity
方法来设置 Toast
在屏幕上的位置
Toast toast = Toast.makeText(getApplicationContext(),
"Hello, The Code Project!", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
第一个参数用于设置 gravity 本身(Gravity
类中有一整套这样的参数)。第二个和第三个参数定义了相对于第一个参数中设置的值,Toast
应该偏移多少像素。执行上述代码的结果如下图所示

向标准 Toast 添加图像
为了向标准 Toast
添加图像,你首先需要创建一个 ImageView
对象,并使用 setImageResource
方法从资源中设置其图像。然后,你需要获取标准视图(实际上是一个 LinearLayout
),并将新创建的 ImageView
对象添加到其中。还需要设置图像需要插入的位置(在我们的例子中,使用 0
,以便图像显示在文本上方)。代码如下所示
Toast toast = Toast.makeText(getApplicationContext(),
"Hello, The Code Project!", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
LinearLayout toastView = (LinearLayout) toast.getView();
ImageView imageCodeProject = new ImageView(getApplicationContext());
imageCodeProject.setImageResource(R.drawable.codeprojectlogo);
toastView.addView(imageCodeProject, 0);
toast.show();
以这种方式创建的 Toast
如下图所示

创建具有自定义布局的 Toast
为了创建具有自定义布局的 Toast
,我们首先需要创建该布局本身。它的代码如下所示
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://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" />
<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
看起来像一个带有标题、图像和消息的对话框。我们现在需要将我们创建的布局设置为 Toast
。我们还应该设置对话框标题、消息文本和图像。这是我们如何做到的
LayoutInflater inflater = getLayoutInflater();
View layout = inflater.inflate(R.layout.customtoast,
(ViewGroup) findViewById(R.id.llToast));
ImageView image = (ImageView) layout.findViewById(R.id.tvImageToast);
image.setImageResource(R.drawable.codeprojectlogo);
TextView title = (TextView) layout.findViewById(R.id.tvTitleToast);
title.setText("Attention");
TextView text = (TextView) layout.findViewById(R.id.tvTextToast);
text.setText("Hello, The Code Project!");
Toast toast = new Toast(getApplicationContext());
toast.setGravity(Gravity.RIGHT | Gravity.TOP, 12, 40);
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(layout);
toast.show();
前两行通过从 XML 文件中膨胀布局来初始化 View
对象(我们使用 LayoutInflater
类的实例,由 getLayoutInflater
返回,来做到这一点)。inflate 方法的第一个参数设置了之前创建的布局的 id - R.layout.customtoast
(它匹配 res/layout/customtoast.xml 文件)。然后,我们获取对图像、标题和消息文本的引用,并使用适当的数据填充它们。最后,我们创建 Toast
本身,设置所有必需的参数以及我们之前创建的布局(这是使用 setView
方法完成的)。因此,我们得到了如下图所示的 Toast

从另一个线程调用 Toast
要从另一个 Thread
调用 Toast
,你需要定义一个 Handler
类型的属性在你的类中
Handler handler = new Handler();
现在,假设你有一个 Thread
,你需要在这个 Thread
中调用一个显示 Toast
的方法
new Thread(new Runnable() {
public void run() {
showToast();
}
}).start();
在这种情况下,该方法将在一个单独的 Thread
中执行。但是因为 Toast
只能在主 Thread
中显示,当你尝试运行它时,你会收到一个错误。
如果你需要在从单独的 Thread
调用时在主 Thread
中执行,你需要一个之前定义的 Handler
。你可以以这种方式从新创建的 Thread
中显示 Toast
public void showToast() {
handler.post(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(),
"Hello, The Code Project!", Toast.LENGTH_SHORT).show();
}
});
}
就是这样。
附注:感谢 Timur Dyussebayev 的英文翻译。
历史
- 2010 年 9 月 14 日:首次发布