Toast是android中用来显示快速显示短信息的一种机制,toast没有焦点,显示的时间是有限制的,过一段时间后会自动消失,不过自己可以控制时间显示的长短。Toast的构建方式有两种,第一种是直接调用构造函数:Toast toast = new Toast(context);
第二种是通过调用Toast类的一个静态方法:Toast toast = Toast.makeText(context, text, duration);
这两种方式是有差别的,看看Toast的源码就明白了,Toast类的构造函数如下:
public Toast(Context context) {
mContext = context;
mTN = new TN(context);
mY = context.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.toast_y_offset);
}
Toast类的静态方法makeText(context, text, duration)源码如下:
public static Toast makeText(Context context, CharSequence text, int duration) {
Toast result = new Toast(context);
LayoutInflater inflate = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflate.inflate(com.android.internal.R.layout.transient_notification, null);
TextView tv = (TextView)v.findViewById(com.android.internal.R.id.message);
tv.setText(text);
result.mNextView = v;
result.mDuration = duration;
return result;
}
Toast类中有个属性mNextView很重要,它是一个View,指定Toast显示的view,当你使用第一种方法得到Toast时,一定要调用Toast的setView(View v)方法为Toast指定一个view,使用第二种方式则不需要显示调用setView(View v),看看上面的这句代码就明白了,result.mNextView = v。
为什么使用第一种方式得到Toast时需要显示指定View呢,看看Toast的show()和setText(CharSequence s):
/**
* Show the view for the specified duration.
*/
public void show() {
if (mNextView == null) {
throw new RuntimeException("setView must have been called");
}
INotificationManager service = getService();
String pkg = mContext.getPackageName();
TN tn = mTN;
try {
service.enqueueToast(pkg, tn, mDuration);
} catch (RemoteException e) {
// Empty
}
}
/**
* Update the text in a Toast that was previously created using one of the makeText() methods.
* @param s The new text for the Toast.
*/
public void setText(CharSequence s) {
if (mNextView == null) {
throw new RuntimeException("This Toast was not created with Toast.makeText()");
}
TextView tv = (TextView) mNextView.findViewById(com.android.internal.R.id.message);
if (tv == null) {
throw new RuntimeException("This Toast was not created with Toast.makeText()");
}
tv.setText(s);
}
如果不指定view,则mNextView的值为null。就会抛出异常。另外使用第一种方式时,就算你为Toast设置好了View也不能这样调用:toast.setText(s);
会抛出This Toast was not created with Toast.makeText()异常。解决的办法是定义一个TextView,然后为TextView赋值,再加到XXLayout中,
使用setView(XXLayout)把XXLayout设置成Toast的View。
下面分别采用两种方式创建Toast
/**
*自定义美化Toast,使用图片作背景
*/
private void showToast() {
Toast t = new Toast(this);
t.setDuration(Toast.LENGTH_SHORT);
LinearLayout layout = new LinearLayout(this);
layout.setBackgroundResource(R.drawable.toast_bg);
TextView textView = new TextView(this);
textView.setText("javaeye:您好!");
textView.setTextSize(14);
textView.setTextColor(Color.WHITE);
layout.addView(textView);
t.setView(layout);
t.setGravity(Gravity.TOP, 100+20, 200 + 20);
t.show();
}
/**
* 默认的Toast效果
*/
private void showToast2() {
Toast t = Toast.makeText(this, "csdn:您好!", Toast.LENGTH_SHORT);
t.setGravity(Gravity.TOP, 100+20, 200 + 20);
t.show();
}