Android系统里面有个东西很好用,也很常用,那就是Toast,但是长期使用也会发现,Toast有他的不足之处:形式单一,只有文字,风格不变等等,那么要如何自定义一个Toast呢,我们可以先从分析Android定义Toast的代码着手:

Toast的makeText方法


Android中如何自己定义吐司(Toast)_第1张图片


这里实际上Android所做的工作是将Toast显示的文本和持续时间设置了一下,然后返回了Toast对象,用以执行show()方法。这里核心的地方是要弄明白


这一句Android做了一些什么工作,下面我们继续看:


Android中如何自己定义吐司(Toast)_第2张图片

这里实际上是new 了一个TN()对象,然后对TN对象设置了一些关于位置和偏移的参数。那么那个TN是何方神圣呢?我们可以继续往下看:




我们可以发现,TN的构造函数里面执行了一个handleShow的方法




我们可以发现handleshow这个方法执行了一大堆的语句,但是实际上我们需要重点关注的只有一句,也就是上面选中的一句:mWM.addView(mView,mParams);


实际上这个mWM是一个WindowManager,mView是要显示的组件的view,而mParams应该是参数的设置一类,但是具体是何方神圣呢?我们可以在Toast类中找到一个成员变量


我们发现mParams实际上是WindowManager的一个布局参数。但是如果单从handleShow方法来看mParams的设置感觉还是太乱,我们可以在Toast中找到下面这一段


Android中如何自己定义吐司(Toast)_第3张图片


在这里我们可以比较清楚看到mParams的一部分主要参数设置,其中包含了长宽都是wrap_content,然后是半透明的(TransLucent),然后还设置了一个动画效果(Animation_Toast),和一个标题(setTitle("Toast"))最后设置了Toast一些标识比如让屏幕亮起,不可触摸,不可获取焦点等。


到这里,我们基本上清楚了Toast是如何显示出来的核心的在于使用一个WindowManager的addView方法,将要显示的view和参数mParams传进来,但是在此之前还需要设置mParams的一些参数;


那么这里是显示,Toast是如何让显示消失的呢?我们可以在handleShow方法下面找到一个handHide的方法




同样核心语句也是选中的一句,mWM.removeView(mView),这样就让Toast消失掉了


那么有了上面的一些分析,我们不难写出我们自己的Toast类,里面提供一些静态方法,让我们来自己定义Toast的显示风格和显示内容,也可以控制Toast的显示开始和结束的时机。

下面的自定义Toast类,提供了几种形式的show方法,可以像传统Toast一样,传入文本来显示一个testview,也可以完全自己定义传入view对象和mParams参数,这样可以定义出了一个完全自己定义的Toast


package com.alexchen.mobilesafeexercise.ui;import android.content.Context;import android.graphics.PixelFormat;import android.view.View;import android.view.WindowManager;import android.widget.TextView;import android.widget.Toast;/** * 自定义吐司 *  * @author Alex *  */public class MyToast {/** * 窗体管理者 */private static WindowManager wm;private static WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();private static View mView;private static TextView tv;/** * 显示自定义吐司 *  * @param info * @param context */public static void show(String message, Context context) {wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);tv = new TextView(context);tv.setText(message);tv.setTextSize(20);// 原来TN所做的工作WindowManager.LayoutParams params = mParams;params.height = WindowManager.LayoutParams.WRAP_CONTENT;params.width = WindowManager.LayoutParams.WRAP_CONTENT;params.format = PixelFormat.TRANSLUCENT;params.type = WindowManager.LayoutParams.TYPE_TOAST;params.setTitle("Toast");params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;wm.addView(tv, params);}/** * 自定义文本吐司的显示方法,这个方法提供了更多自定义的内容,比如textview可以应用一个传入的style的id *  * @param message * @param context * @param textViewResid * @param params */public static void show(String message, Context context, int textViewResid,WindowManager.LayoutParams params) {wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);tv = new TextView(context);// 多加了一个风格tv.setTextAppearance(context, textViewResid);// 原来TN所做的工作// WindowManager.LayoutParams params = mParams;// params.height = WindowManager.LayoutParams.WRAP_CONTENT;// params.width = WindowManager.LayoutParams.WRAP_CONTENT;// params.format = PixelFormat.TRANSLUCENT;// params.type = WindowManager.LayoutParams.TYPE_TOAST;// params.setTitle("Toast");// params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON// | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE// | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;wm.addView(tv, params);}/** * 更多自定义的形式,可以直接传入任一个自己定义好的view,自己设置wm的参数 *  * @param view * @param context * @param params *            WindowManager.LayoutParams类型的参数, WindowManager.LayoutParams *            mParams = new WindowManager.LayoutParams(); params.height = *            WindowManager.LayoutParams.WRAP_CONTENT; params.width = *            WindowManager.LayoutParams.WRAP_CONTENT; params.format = *            PixelFormat.TRANSLUCENT; params.type = *            WindowManager.LayoutParams.TYPE_TOAST; *            params.setTitle("Toast"); params.flags = *            WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | *            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | *            WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; */public static void show(View view, Context context,WindowManager.LayoutParams params) {wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);MyToast.mView = view;wm.addView(mView, params);}/** * 隐藏自定义吐司 这里一定要记得判空一下,因为平时没有打电话时,这两个量应该都是空的 */public static void hide() {if (wm != null) {if (tv != null) {wm.removeView(tv);tv = null;}if (mView != null) {wm.removeView(mView);mView = null;}if (tv == null && mView == null) {wm = null;}}}}



更多相关文章

  1. Android网络编程之通过Get方法实现
  2. Android实现自定义滑动式抽屉效果菜单
  3. 自定义RadioButton样式并去除默认样式位置【Android】
  4. android控件的监听绑定方法
  5. 全面的Android文件目录解析和获取方法(包含对6.0系统的说明)
  6. Android官方的文档中提到了模拟器中设置代理服务器的方法,即在命
  7. 如何向Android的framework里添加新类 &&& android修改开放类方法
  8. Android swap分区作用及swapper软件设置方法

随机推荐

  1. JavaScript 中的强制类型转换[每日前端夜
  2. 大江大河,一代人的缩影。
  3. 用Python生成抖音字符视频!
  4. 用Python将HTML转为PDF。
  5. 怎样与 CORS 和 cookie 打交道[每日前端
  6. 我怎样用Node.js自动完成工作的[每日前端
  7. 学习C语言的历程
  8. 为什么GraphQL是API的未来[每日前端夜话0
  9. 新浪微博评论爬取。
  10. 如何用WebAssembly为Web应用提速20倍