前言

  相信有些人用过MIUI,会发现小米的Toast跟Android传统的Toast特么是不一样的,他会从底部向上飞入,然后渐变消失。看起来效果是挺不错的,但是对于Android原生Toast是不支持自定义动画的。那这个效果到底是怎么实现的呢?下面就来告诉你。。。。

分析

  如果园友看过我的另一篇博客《Android:剖析源码,随心所欲控制Toast显示》,就会知道其实原生Toast就是infate出一个View实例,然后将其加载到WindowManager上面来达到显示效果。我们很多人都知道WindowManager是可以实现一个悬浮在所有应用界面的视图而不会获取焦点,这也就是Toast所需要具备的核心的功能:简约提示信息传递给用户,而不额外执行其他操作;在这里,我们这个效果也是基于WindowManager来实现的。

正文

  我们需要自定义一个Toast的类,但是不需要继承Toast。既然是仿照着写一个自定义Toast,那么我们就从Toast的入口开始完善这个自定义Toast。

新建一个类

view source print ? 1. public class MiuiToast { 2.   3. }

干干净净的不用去继承其他类(除了Object.......)

开始码代码

我们一般使用原生Toast都是直接 Toast.makeText(this, text, Toast.LENGTH_SHORT).show(); 其中makeText这个静态方法会返回一个Toast实例,然后调用show方法来显示Toast。

我们先来搞定makeText方法

view source print ? 1. public static MiuiToast MakeText(Context context, String text, boolean showTime) { 2. MiuiToast result = new MiuiToast(context, text, showTime); 3. return result; 4. }

逻辑简单粗暴,直接调用构造函数实例化一个MiuiToast对象并返回。

接下来该是MiuiToast的构造方法了

view source print ? 01. private MiuiToast(Context context, String text, boolean showTime ){ 02. mShowTime = showTime;//记录Toast的显示长短类型 03. mIsShow = false;//记录当前Toast的内容是否已经在显示 04. mWdm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 05. //通过Toast实例获取当前android系统的默认Toast的View布局 06. mToastView = Toast.makeText(context, text, Toast.LENGTH_SHORT).getView(); 07. mTimer = new Timer(); 08. //设置布局参数 09. setParams(); 10. }

在构造方法中,更多的是对数据的初始化,由于设置布局参数比较多,所以单独抽出一个函数来

瞧瞧setParams()方法

view source print ? 01. private void setParams() { 02. mParams = new WindowManager.LayoutParams(); 03. mParams.height = WindowManager.LayoutParams.WRAP_CONTENT;  04. mParams.width = WindowManager.LayoutParams.WRAP_CONTENT;  05. mParams.format = PixelFormat.TRANSLUCENT;  06. mParams.windowAnimations = R.style.anim_view;//设置进入退出动画效果 07. mParams.type = WindowManager.LayoutParams.TYPE_TOAST;  08. mParams.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON  09. | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE  10. | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 11. mParams.gravity = Gravity.CENTER_HORIZONTAL; 12. mParams.y = 250; 13. }

这个设置参数更多是参考源代码中原生Toast的设置参数的类型,在这里我们需要注意的是 mParams.windowAnimations = R.style.anim_view;//设置进入退出动画效果,这个使我们这个仿MIUI的Toast动画实现的基石。其他参数也没什么好讲的,谷歌就是这么设置他们的Toast的哈,接下来我们得看看动画的配置XML。

这个R.style.anim_view的情况呢

view source print ? 1. 2. 6.

这里定义了一个进入动画和退出动画的引用,接下来就是我们设置动画效果的时刻了!

anim_in:Toast的进入动画

view source print ? 01. 'http://schemas.android.com/apk/res/android'> 02. 03. android:fromXDelta='0' 04. android:fromYDelta='0' 05. android:toXDelta='0' 06. android:toYDelta='85' 07. android:duration='1' 08. /> 09. 10. android:fromXDelta='0' 11. android:fromYDelta='0' 12. android:toXDelta='0' 13. android:toYDelta='-105' 14. android:duration='350' 15. android:fillAfter='true' 16. android:interpolator='@android:anim/decelerate_interpolator' 17. /> 18. 19. android:fromAlpha='0' 20. android:toAlpha='1' 21. android:duration='100' 22. /> 23. 24. android:fromXDelta='0' 25. android:fromYDelta='0' 26. android:toXDelta='0' 27. android:toYDelta='20' 28. android:duration='80' 29. android:fillAfter='true' 30. android:startOffset='350' 31. /> 32.

在这里我配置了四个动画效果,如果大家要重新设置新的动画效果,尽可以在这里面修改哈。粗略的说几句,由于在加载动画的前后,WindowManager就通过mParams来确定Toast的显示位置,所以第一个translate作用是让Toast在开始载入的时候跳转到进入的位置,而其他的动画就是完成Toast从下端飞入的效果而已,这期间利用了android:startOffset进行时间的控制达到动画的衔接效果。

anim_out:Toast退出动画

view source print ? 1. 'http://schemas.android.com/apk/res/android'> 2. 3. android:fromAlpha='1' 4. android:toAlpha='0' 5. android:duration='800'/> 6.

简简单单的一个淡出动画。。。。

然后我们来看下show()方法吧

view source print ? 01. public void show(){ 02. if(!mIsShow){//如果Toast没有显示,则开始加载显示 03. mIsShow = true; 04. mWdm.addView(mToastView, mParams);//将其加载到windowManager上 05. mTimer.schedule(new TimerTask() { 06. @Override 07. public void run() { 08. mWdm.removeView(mToastView); 09. mIsShow = false; 10. } 11. }, (long)(mShowTime ? 3500 2000)); 12. } 13. }

在show方法中我们会对mIsShow 判断当前的Toast是否已经在显示,如果正在显示我们没理由相信我们会那么SB得再去显示他一次。。

mWdm.addView(mToastView, mParams);将View加载到WindowManager上面,达到类似的悬浮效果,启动定时器,到达指定的时间后将其移除,整个逻辑就是这样了。

因为——Toast!就是这么简单!

给大家瞄瞄效果图

转载于:https://www.cnblogs.com/rabbit-bunny/p/4241248.html

更多相关文章

  1. Android(安卓)Studio如何import module(针对非gradle)
  2. Android(安卓)属性动画代码分析(基于ObjectAnimator)
  3. Android(安卓)高仿微信发朋友圈浏览图片效果
  4. 腾讯Android社招面试源码相关11题+原理详解
  5. android 显示图片的指定位置图像 ImageView ImageButton
  6. [置顶] android图形系统详解六:View layer
  7. Android(安卓)API Guiede---Animation and Graphics
  8. App启动时三种效果(黑屏白屏、背景图片、延迟加载)
  9. Android(安卓)实现高斯模糊效果及低版本兼容

随机推荐

  1. Android Content Provider详解及示例代码
  2. android 应用自动升级
  3. android点滴23:android library projects
  4. android日历之滚动选择日期类似ios
  5. Android菜鸟的成长笔记(4)——你真的理解了
  6. Android ADB 源码分析总结
  7. adb shell命令大全
  8. EditText 不显示光标 光标消失
  9. Android修炼之道——Shape
  10. android基于dialog加载时转圈圈的demo