随笔 - 23  文章 - 0  评论 - 108 

前言

  Toast,这个曾经也是现在正在迷倒万千软件开发者尤其是android开发者的小美女,向来不乏在各个明星应用中频繁登场。Toast是神马~听说是一种吐司面包,能吃吗?如果手机屏幕是巧克力做的,我觉得兴许味道还不错的说。言归正传,先来说一说Toast的应用场景,毕竟Toast哥也是见过大场面的人儿了。张三正打算拿在移动互联网上冲一个浪,突然Toast一个:“网络不给力啊,我都拿不到数据了”;李四要安装应用到内存卡,这时Toast一个:“你穷的连内存卡都买不起呀,我都找不着地儿安装了”;王五玩累游戏要退出应用,退出时Toast一个:“别这样嘛,你真要走了?”。所以,鉴于Toast哥已经遍布在大街小巷的种种应用中深入人心,这个Toast我们不应该好好玩转一下吗?想想还有点小激动呢。

  但是现在有人要说了,Toast一个还不容易?直接

Toast.makeText(MainActivity.this, “Toast一下”, Toast.LENGTH_LONG).show();

不就出现了,这还有什么好研究的吗?那么,我恭喜你,你掌握了Toast的最基本的用法,也具备了读懂接下来所需的储备知识。

  那么问题来了:我们应该掌握Toast的哪些基础知识呢?

-----------------------------------------我是分割线(本篇博客立足基础,后面将会发布两篇干货的Toast博客)--------------------------------------------

 普通的Toast

  所谓万丈高楼平地起,,D罩胸围A罩起;基础扎实了,啥都不是事儿。案例驱动,往往是最好理解滴~

  某天小明菜鸟接到一个活儿,老大叫他把应用中的出意外的地方(参考网络出错、误操作)向用户展示出来,但并不需要用户回馈。小明这时信心满满了,就这点功能,可不就是Toast就可以完美解决的吗。在程序中需要的地方ctrl+c and ctrl+v 下面代码,三下五除二的就搞定了,恩,就是这样了。

Toast.makeText(MainActivity.this, “Toast一下”, Toast.LENGTH_LONG).show();

小明虽然是菜鸟但是很好学的,不仅把代码糊弄好了,顺便也研究了一下Toast的基本用法,总结出几条:

1、Toast.makeText()会返回Toast实例,我们可以先获取Toast实例,再调用Show()方法显示。

2、Toast不会占据焦点,也不会遮挡后面的Activity导致其进入生命周期变换。

提示用户,Toast一下!”小明在泛黄的笔记本上记下了这句箴言。

给Toast挪挪位置

  第二天小明心血来潮的测试了下软件,发现Toast经常把位于稍微靠近底部的用户按钮给时不时遮盖了一下,虽然不影响Button的事件触发,但是心里的那个别扭呀。不行,给它挪挪窝先,所以小明看遍了博客园的一些小道文章,终于有一个重大的发现,可以通过setGravity()来改变Toast的显示位置!话不多说,代码出炉:

Toast toast = Toast.makeText(MainActivity.this, R.string.user_defined_location, Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, -50);
toast.show();

终于把Toast拉到屏幕居中(Gravity.CENTER_VERTICAL),但是小明嫌中间不好,有在竖直方面往上移动了50距离,效果出来了。

这么简单就解决了,小明肯定不会仅仅满足于此,所以对setGravity(gravity, xOffset, yOffset)也进行了简单的分析:

1、gravity是输入Toast需要显示的位置,例如CENTER_VERTICAL(垂直居中)、CENTER_HORIZONTAL(水平居中)、TOP(顶部)等等。

2、xOffset则是决定Toast在水平方向(x轴)的偏移量,偏移量单位为,大于0向右偏移,小于0向左偏移,等于0由于小明太懒所以没解释。

3、yOffset决定Toast在垂直方向(y轴)的偏移量,大于0向下偏移,小于0向上偏移,末了小明加了个PS:想设大值也没关系,反正Toast不会跑出屏幕。

 在Toast加上个Logo

  小明用Toast用着用着就觉得老单调了,就像老婆一样看久了就觉得没追求她的时候漂亮了一样(偶除外!)。突然觉得能在Toast的时候加个Logo图标有种高大上的感觉,那么问题来了:小明要怎么做才能实现这种效果呢?度娘永远是一个好老师,小明发现了这么一段代码:

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

小明happy的将代码copy进工程里面,里面就出现了效果:

呼呼(~ o ~)~zZ。。。小明注意到了注释里面强调为用线性布局,为啥呢?鉴于这篇博客主要讲的是基础,所以不在此分析源码,只强调一下Toast布局在源码中的布局是采用LinearLayout,所以大家getView的时候自觉点转成线性布局就行了。

完全定制一个Toast

  小明在捣鼓Toast加Logo的过程中,发现了另外一个setView()方法。额,既然getView()是获取Toast的布局,按小明攻城狮的思维来说,setView()毫无疑问是设置Toast的布局,“如果不是偶就直播吃翔!”小明踌躇满志的说,既然发现了这个神奇的东东,小明觉得加个Logo不如来个完全定制。人生少不了几次说走就走的旅行,码代码当然也不能少几次说干就干的激情。

Toast完全定制代码:

Toast toast = Toast.makeText(MainActivity.this, R.string.user_defined_picture, Toast.LENGTH_LONG);
LinearLayout toastView = (LinearLayout) LayoutInflater.from(MainActivity.this).inflate(R.layout.toast_view, null);
toast.setView(toastView);
toast.show();

xml布局文件很简单:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical" >
        <TextView 
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:text="@string/user_defined_all"
            />
        <ProgressBar 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            />
</LinearLayout>

成果如下:

天佑小明呀,逃脱了直播的命运;完全在小明的预料中,一个暂时的自定义Toast就出现的眼前。

镜头转到小明面前,一脸冷笑:“呵呵~”。

 异步运行Toast

  过几天后,小明遇到一个大难题了,需要在点击的某个时间后显示Toast,也就是要异步执行Toast.show()。小明先是new 了一个Thread子线程,到规定的时间后就调用Toast.show()。但是但是,Logcat给出了一大堆红叉叉报错!!!!这可愁坏小明了,既然用开启子线程的办法Toast会报错,那么问题来了:怎样才可以在按需完成任务呢?

方法一:既然在子线程中报错,那么我们就借用Handler来在消息队列中执行。

handler.post(new Runnable() {
  @Override
  public void run() {
    Toast.makeText(MainActivity.this, R.string.other_thread, Toast.LENGTH_LONG).show();
  } });

PS:该Runnable是在主线程中执行run的,具体请参加谷歌文档。所以不会出现报错。

方法二:我们可以强行在子线程中执行,只需要获取Looper。

new Thread(){
  @Override
    public void run(){
      Looper.prepare();
      Toast.makeText(MainActivity.this, R.string.other_thread, Toast.LENGTH_LONG).show();
      Looper.loop();
      Log.i("text", "注意:Looper.loop()后面的代码不会被执行");//LogCat无输出
    }
  }.start();

对于这个Toast在异步运行,也没什么需要小明解释的。但是在后面将要写的剖析Toast的进阶博客中,这点需要掌握了才能更好的全方位定制我们所需要的Toast。

 

如果觉得写得还可以的就点个赞n(*≧▽≦*)n。。。。。。更要谢谢大家花时间看这篇基础博客。

 

作者:enjoy风铃
出处:http://www.cnblogs.com/net168/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则下次不给你转载了。

posted on 2014-10-22 00:05 码农叔叔 阅读(...) 评论(...) 编辑 收藏