好吧,知识来源于实践。最近项目有一个功能,要在全局范围内实现提示功能,最后采用了Toast的方式(没办法,这种app级的弱提示,还是Toast来的方便),研究了下源码,做了一个自定义的吐司。记录一下。

Toast 应该接触过android的都知道,而且应用起来相当简单。

Toast.makeText(context, message, Toast.LENGTH_SHORT).show();

上面的是最简单的Toast应用,Toast类的makeText方法有三个参数,上下文,提示内容和显示时间(Toast中给出两种选择。Toast.LENGTH_SHORT:2000ms, Toast.LENGTH_LONG:3500ms),然后此方法返回一个Toast类的实例。在调用show()方法,显示出来。

大家用toast的时候,可能注意到了,当一个按钮点击事件弹出吐司的时候,如果我们一直点,它就会一直提示,当我们停止动作的时候,也会响应一段时间,这就说明,toast不是实时响应的,内部应该有一个队列。这个后面讲原理的时候,会详细说明。

SDK中的Toast功能还是有很多种实现的,用起来还是很方便的:

更改显示位置

Toast toast = Toast.makeText(MainActivity.this, "欢迎光临阿东的博客", Toast.LENGTH_LONG);toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);toast.show();

主要方法 setGravity(int gravity, int xOffset, int yOffset) ,第二个参数和第三个参数对应X轴和Y轴的偏移量

添加View

Toast toast = Toast.makeText(MainActivity.this, "欢迎光临阿东的博客", Toast.LENGTH_LONG);LinearLayout toastView = (LinearLayout) toast.getView();// 获取Toast的LinearLayout,注意需要是线性布局ImageView image = new ImageView(MainActivity.this);image.setImageResource(R.drawable.ic_launcher);// 生成一个现实Logo的ImageViewtoastView.addView(image);// 将ImageView加载到LinearLayout上面toast.show();

说到这,我贴一下Toast布局的源码吧,看代码,一目了然

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>  

自定义View

当然,添加view,限制太大,还是自定义来的实在。

Toast toast = Toast.makeText(MainActivity.this, "欢迎光临阿东的博客", Toast.LENGTH_LONG);LinearLayout toastView = (LinearLayout) LayoutInflater.from(MainActivity.this).inflate(R.layout.toast_view, null);toast.setView(toastView);toast.show();

子线程中执行

有的情况下我们可能需要Toast在子线程中执行,但是Toast内部用到了handler(看到有人有疑问,这只用到了Looper,并没有用到handler,那请你往里看看Toast的源码,TN类中是有使用handler的),大家知道handler必须依靠looper传递消息,所以必须在Toast前调用Looper.prepare();来注册当前Thread的looper。在Toast之后调用Looper.loop();让looper开始工作。如果有人有这样的疑问,我平时用的Toast也没有用到Looper啊,那是因为大多数情况下,Toast都是在主线程中使用,主线程中默认是开启looper的。
    Thread thread = new Thread(new Runnable(){        @Override        public void run(){            Looper.prepare();            Toast.makeText(getActivity(), "欢迎来到阿东的博客", Toast.LENGTH_SHORT).show();            Looper.loop();        }    });    thread.start(); 

本想在本文把Toast的源码分析给大家,但是限于篇幅,还是分开写了。
想要看源码分析的话,请移步 《Android:Toast源码分析》

更多相关文章

  1. android语音识别方法示例代码
  2. Android TV 焦点原理源码解析
  3. Android下java方法和JS方法的互调
  4. Android 中LayoutInflater(布局加载器)源码篇之parseInclude方法
  5. Android 中LayoutInflater(布局加载器)源码篇之rInflate方法
  6. Android解析Intent Filter的方法
  7. android中访问本机服务器的方法

随机推荐

  1. android的编译和运行过程深入分析
  2. Android的 linux内核
  3. Android能用Linux打败Linux手机吗?
  4. 你的手机到底安不安全?看看Android和iOS是
  5. Android的消息机制,用Android线程间通信的
  6. webrtc 之android与PC互通
  7. android:configChanges
  8. android基本架构
  9. android kernel 初始化 1
  10. android TextView 走马灯效果