Android -Toast源码解析

Toast是Android中用来显示显示信息的一种机制,和Dialog不一样的是,Toast是没有焦点的,而且Toast显示的时间有限,过一定的时间就会自动消失。系统的Toast使用很简单,只需要一行代码就可以搞定,不过样式相对单一,下面就来研究一下花样的Toast。


说到Toast,最常用的方法应该就是makeText方法,看一下源码中的makeText方法:

public static Toast makeText(Context context, CharSequence text, @Duration 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;
}

使用这个方法需要传入三个参数,第一个是上下文对象、第二个是要显示的信息text、第三个是Toast的显示时间。

这个方法会返回一个Toast对象,Toast的布局是使用LayoutInflater方法动态载入的。使用findViewById方法拿到布局中的TextView对象,设置TextView的text为我们传入的text参数。

最后设置Toast的显示View为v,显示时间是我们传入的时间参数。

再看一下,这个方法中引入的View布局源码(transient_notification.xml)如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   
android:layout_width="match_parent"
   
android:layout_height="match_parent"
   
android:orientation="vertical"
   
android:background="?android:attr/toastFrameBackground">

   <TextView
       
android:id="@android:id/message"
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:layout_weight="1"
       
android:layout_gravity="center_horizontal"
       
android:textAppearance="@style/TextAppearance.Toast"
       
android:textColor="@color/bright_foreground_dark"
       
android:shadowColor="#BB000000"
       
android:shadowRadius="2.75"/>

</LinearLayout>

设置了layout_gravity属性为水平居中,textAppearance用于设置字体外观样式,shadowColor属性设置阴影颜色,shadowRadius属性设置阴影的半径。

除了这个用的非常多的方法外,Toast类还提供了如下方法:

一、设置Toast的位置(第一个是Gravity类型,第二个是X轴偏移,第二个是Y轴偏移):

public void setGravity(int gravity, int xOffset, int yOffset) {
   mTN.mGravity = gravity;
   
mTN.mX = xOffset;
   
mTN.mY = yOffset;
}

二、设置Toast的显示文字:

public void setText(@StringRes int resId) {
   setText(mContext.getText(resId));
}

三、设置Toast的显示时间:

public void setDuration(@Duration int duration) {
   mDuration = duration;
}

四、设置Toast的显示布局:

public void setView(View view) {
   mNextView = view;
}

五、取消Toast的显示:

public void cancel() {
   mTN.hide();

   try
{
       getService().cancelToast(mContext.getPackageName(), mTN);
   
} catch (RemoteException e) {
       // Empty
   
}
}

下面通过一个实例学习一下上面这些方法的用法,自定义的Toast的布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
   
android:layout_width="fill_parent"
   
android:layout_height="fill_parent"
   
android:background="#ffffff"
   
android:orientation="vertical"
   
android:padding="5dp">

   <ImageView
       
android:id="@+id/img"
       
android:layout_gravity="center_horizontal"
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content" />

   <TextView
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:text="带图片文字的Toast" />
</LinearLayout>

MainActivity.java:

public class MainActivity extends AppCompatActivity {
   private Button mButton;
   private
Button mButtonCancel;
   private
Button mButtonView;
   
Toast mToast;

   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       
setContentView(R.layout.activity_main);
       
mButton = (Button) findViewById(R.id.btn);
       
mButtonCancel = (Button) findViewById(R.id.btn_cancel);
       
mButtonView = (Button) findViewById(R.id.btn_setView);
       
mButtonView.setOnClickListener(new View.OnClickListener() {
           @Override
           
public void onClick(View v) {
               //将一个xml布局转换成一个view对象
               
LayoutInflater inflater = (LayoutInflater)
                       getSystemService(Context.LAYOUT_INFLATER_SERVICE);
               
View view = inflater.inflate(R.layout.toast_layout, null);

               
Toast toast = new Toast(getApplicationContext());
               
//在view中查找查找ImageView控件
               
ImageView image = (ImageView) view.findViewById(R.id.img);
               
image.setImageResource(R.mipmap.ic_launcher);
               
toast.setView(view);
               
toast.show();
           
}
       });
       
mButtonCancel.setOnClickListener(new View.OnClickListener() {
           @Override
           
public void onClick(View v) {
                  mToast.cancel();//取消显示
           
}
       });
       
mButton.setOnClickListener(new View.OnClickListener() {
           @Override
           
public void onClick(View v) {
                       mToast = Toast.makeText(MainActivity.this,
                       
"设置Gravity方法", Toast.LENGTH_LONG);
               
mToast.setGravity(Gravity.TOP, 0, 100);//x偏移量为0,y偏移量为100
               
mToast.show();
           
}
       });
   
}
}

运行实例如下:


点击setGravity按钮,Toast显示在顶部,点击Cancel按钮,Toast取消显示,点击setView按钮显示自定义布局的Toast。

大周末更新文章不易,欢迎转发,谢谢,嘿嘿

谢谢关注我的微信公众号,觉得好可以分享到朋友圈哦.

请关注我的新浪微博:AndroidTip

CSDN博客:http://blog.csdn.net/yayun0516

发布了498 篇原创文章 · 获赞 115 · 访问量 126万+

猜你喜欢

转载自blog.csdn.net/yayun0516/article/details/52713360