前言

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

分析

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

正文

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

新建一个类

public class MiuiToast {}

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

开始码代码

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

我们先来搞定makeText方法

public static MiuiToast MakeText(Context context, String text, boolean showTime) {    MiuiToast result = new MiuiToast(context, text, showTime);    return result;}

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

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

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

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

瞧瞧setParams()方法

private void setParams() {    mParams = new WindowManager.LayoutParams();    mParams.height = WindowManager.LayoutParams.WRAP_CONTENT;      mParams.width = WindowManager.LayoutParams.WRAP_CONTENT;      mParams.format = PixelFormat.TRANSLUCENT;      mParams.windowAnimations = R.style.anim_view;//设置进入退出动画效果    mParams.type = WindowManager.LayoutParams.TYPE_TOAST;      mParams.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON              | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE              | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;    mParams.gravity = Gravity.CENTER_HORIZONTAL;    mParams.y = 250;}

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

这个R.style.anim_view的情况呢

<resources>    <style name="anim_view">        <item name="@android:windowEnterAnimation">@anim/anim_in</item>        <item name="@android:windowExitAnimation">@anim/anim_out</item>    </style></resources>

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

anim_in:Toast的进入动画

<set xmlns:android="http://schemas.android.com/apk/res/android">    <translate        android:fromXDelta="0"        android:fromYDelta="0"        android:toXDelta="0"        android:toYDelta="85"        android:duration="1"        />    <translate        android:fromXDelta="0"        android:fromYDelta="0"        android:toXDelta="0"        android:toYDelta="-105"        android:duration="350"        android:fillAfter="true"        android:interpolator="@android:anim/decelerate_interpolator"        />    <alpha         android:fromAlpha="0"        android:toAlpha="1"        android:duration="100"        />    <translate        android:fromXDelta="0"        android:fromYDelta="0"        android:toXDelta="0"        android:toYDelta="20"        android:duration="80"        android:fillAfter="true"        android:startOffset="350"        /></set>

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

anim_out:Toast退出动画

<set xmlns:android="http://schemas.android.com/apk/res/android">    <alpha         android:fromAlpha="1"        android:toAlpha="0"        android:duration="800"/></set>

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

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

public void show(){    if(!mIsShow){//如果Toast没有显示,则开始加载显示        mIsShow = true;        mWdm.addView(mToastView, mParams);//将其加载到windowManager上        mTimer.schedule(new TimerTask() {            @Override            public void run() {                mWdm.removeView(mToastView);                mIsShow = false;            }        }, (long)(mShowTime ? 3500 : 2000));    }}

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

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

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

给大家瞄瞄效果图

Android应用系列:仿MIUI的Toast动画效果实现(有图有源码)

源码请戳这里(点我吧)

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

更多相关文章

  1. 使用千千静听或手动创建Android播放列表的方法
  2. Android日志打印类LogUtils,能够定位到类名,方法名以及出现错误的
  3. Android操作SQLite数据库(增、删、改、查、分页等)及ListView显
  4. Android退出应用的方法总结
  5. 改进Android语音对讲系统的方法
  6. Android Scroll分析 (一) 滑动效果是如何产生的

随机推荐

  1. Android(安卓)SparseArray源码阅读
  2. Android、JUnit深入浅出(七)——总…
  3. 生成Google Map KeyGen
  4. Android(安卓)中sqlite数据库的增删改查
  5. Android增加监听的三种实现方式
  6. Android(安卓)okHttp上传图片
  7. android 命令行执行java 的方式
  8. Android(安卓)Webview解析
  9. android 9.0 startService启动Servcie的
  10. android获取手机信息以及服务商信息