65.9K
CodeProject 正在变化。 阅读更多。
Home

Toast: 用户通知

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (38投票s)

2010年9月14日

CPOL

4分钟阅读

viewsIcon

124489

downloadIcon

2594

如何创建不同的 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 如下图所示

toast1.png

设置 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 应该偏移多少像素。执行上述代码的结果如下图所示

toast2.png

向标准 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 如下图所示

toast3.png

创建具有自定义布局的 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

toast4.png

从另一个线程调用 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 日:首次发布
© . All rights reserved.