Android自定义Toast总结
最近工作中遇到一个这样的场景:看电视时,当用户换台时,我们想要提示用户当前频道名称及节目内容,并且为了醒目,我们还要同时把台标也显示出来。
很常见的一个场景,相信大家都遇到过。当然,实现也很方便,我们可以通过显示\隐藏View、PopupWindow、自定义Dialog等实现它。可是这次我希望通过自定义Toast来实现。
自定义Toast的显示内容
根据需求,我们要显示的不仅仅是一段文字,还有图片等内容。因此,我们需自定义Toast的显示内容。那么,该如何做呢?
我们发现,在Toast类中有如果的一个方法:
/**
* Set the view to show.
* @see #getView
*/
public void setView(View view) {
mNextView = view;
}
也就是说,我们可以自定义一个View,然后通过该方法来设置Toast的显示内容。那么接下来的步骤就简单了,就是一个自定义View的过程。
自定义View的步骤
- 完成该View的布局文件
- 在代码中加载该View
- 将View添加到Toast
我们在layout目录下新建一个banner.xml文件。
banner.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_bazinga"
android:layout_width="300dp"
android:layout_height="300dp"
android:background="#00000000"
>
<ImageView
android:id="@+id/view_bazinga"
android:scaleType="centerInside"
android:layout_width="300dp"
android:layout_height="300dp"
android:background="@drawable/bkg_bazinga_3"
/>
</RelativeLayout>
然后我们在代码中inflate该布局文件,得到一个自定义View
LayoutInflater mInflater = LayoutInflater.from(mContext);
View bazingaView = mInflater.inflate(R.layout.bazinga, null);
然后我们再把该自定义View通过setView方法添加到Toast
Toast toast = new Toast(mContext);
toast.setView(bazingaView);
toast.setDuration(Toast.LENGTH_LONG);
toast.show();
因为自定义View的xml文件我们可以自由定义,因此,Toast所显示的内容完全可以自由改变。就这样,我们实现了对Toast显示内容的自定义。这也是自定义View最常见的一种方式,应用十分广泛。
多个Toast连续出现时避免重复
虽然我们实现了自定义Toast,但是,在使用时发现,当我们连续多次换台时,Toast会持续很长一段时间。为什么呢?原来Toast每次只会显示一个,假如上一个还没显示完,下一个就来了,Android并不会取消上一个的显示,而是要等待上一个显示完了,才显示这个。因此,多次连续换台时Toast显示的时间就特别长。
而我们希望的是,无论连续多少次换台,当我们停止换台时,Toast就几秒钟立刻停止显示。那么,该如何实现呢?
要实现其实很简单,基本思路如下:因为无论何时,用户看到的只会是一个Toast,因此,我们只在用户第一次换台时新建一个Toast,之后的每次换台,我们只是改变该Toast的显示内容。这样就避免了多个Toast重复出现。这样,就不存在上个Toast还未显示完成下个就来的问题。每次换台,Toast显示的都是最新的换台信息。
大致代码如下:
public class MyToast {
private Toast mToast;
private View mView;
private Context mContext;
private TextView mText;
public MyToast(Context context){
this.mContext = context;
mToast = new Toast(mContext);
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
mView = layoutInflater.inflate(R.layout.bazinga, null);
mText = (TextView)mView.findViewById(R.id.text_channel);
}
public void show(String channelName){
mText.setText(channelName);
mToast.setView(mView);
mToast.show();
}
}
就这样,通过简单的几行代码,就避免了多个Toast重复显示的问题。这个思想的应用十分广泛,还是希望大家能够理解并掌握。
以上,我们基本实现了我们刚开始时提到的需求,而且代码逻辑也很清晰,效率也很高。