前言

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

分析

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

正文

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

新建一个类

1.public class MiuiToast {
2. 
3.}

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

开始码代码

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

我们先来搞定makeText方法

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的构造方法了

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()方法

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的情况呢

1.<resources>
2.<style name='anim_view'>
3.<item name='@android:windowEnterAnimation'>@anim/anim_in</item>
4.<item name='@android:windowExitAnimation'>@anim/anim_out</item>
5.</style>
6.</resources>

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

anim_in:Toast的进入动画

02.<translate
03.android:fromXDelta='0'
04.android:fromYDelta='0'
05.android:toXDelta='0'
06.android:toYDelta='85'
07.android:duration='1'
08./>
09.<translate
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.<alpha
19.android:fromAlpha='0'
20.android:toAlpha='1'
21.android:duration='100'
22./>
23.<translate
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.</set>

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

anim_out:Toast退出动画

2.<alpha
3.android:fromAlpha='1'
4.android:toAlpha='0'
5.android:duration='800'/>
6.</set>

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

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

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!就是这么简单!

给大家瞄瞄效果图

Android应用系列:仿MIUI的Toast动画效果实现的更多相关文章

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

    前言 相信有些人用过MIUI,会发现小米的Toast跟Android传统的Toast特么是不一样的,他会从底部向上飞入,然后渐变消失.看起来效果是挺不错的,但是对于Android原生Toast是不支持 ...

  2. ToastMiui【仿MIUI的带有动画的Toast】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 仿MIUI的带有动画的Toast 效果图 代码分析 ToastMiui类基于WindowManager 为了和Toast用法保持一致 ...

  3. javascript仿天猫加入购物车动画效果

    javascript仿天猫加入购物车动画效果   注意:首先需要声明的是:代码原思路不是我写的,是在网上找的这种效果,自己使用代码封装了下而已:代码中都有注释,我们最主要的是理解抛物线的思路及在工作中 ...

  4. 仿网易nec首页动画效果

    仿网页nec首页动画效果nec链接:http://nec.netease.com/ 首先,介绍animationanimation检索或设置对象所应用的动画特效.animation由“keyframe ...

  5. 转:Android ViewPager多页面滑动切换以及动画效果

    一.首先,我们来看一下效果图,这是新浪微博的Tab滑动效果.我们可以手势滑动,也可以点击上面的头标进行切换.与此同方式, 白色横条会移动到相应的页卡头标下.这是一个动画效果,白条是缓慢滑动过去的.好了 ...

  6. Android ViewPager多页面滑动切换以及动画效果

    一.首先,我们来看一下效果图,这是新浪微博的Tab滑动效果.我们可以手势滑动,也可以点击上面的头标进行切换.与此同方式,白色横条会移动到相应的页卡头标下.这是一个动画效果,白条是缓慢滑动过去的.好了, ...

  7. Android——ViewPager多页面滑动切换以及动画效果

    一.首先,我们来看一下效果图,这是新浪微博的Tab滑动效果.我们可以手势滑动,也可以点击上面的头标进行切换.与此同方式,白色横条会移动到相应的页卡头标下.这是一个动画效果,白条是缓慢滑动过去的.好了, ...

  8. 【Android初级】如何实现一个有动画效果的自定义下拉菜单

    我们在购物APP里面设置收货地址时,都会有让我们选择省份及城市的下拉菜单项.今天我将使用Android原生的 Spinner 控件来实现一个自定义的下拉菜单功能,并配上一个透明渐变动画效果. 要实现的 ...

  9. android自定义view仿照MIUI中音量控制效果

    先看效果图: 这就是miui中的音量效果图,实现思路是自定义视图,绘制圆环,然后设置进度显示. 核心代码在onDraw中实现如下: @Override protected void onDraw(Ca ...

随机推荐

  1. JavaScript中:地址引用的特性,导致静态初始值被修改

    问题分类 JavaScript,值引用,地址引用 问题描述 开发过程中,服务端将静态配置数据从mysql数据库中读取到内存中,方便调用. 在实现流派功能时,需从数据库中读取流派种类数据到内存中,由于其 ...

  2. SPOJ 703 SERVICE - Mobile Service 题解

    题面 好题啊!~ 设f[i][j][k][l]表示已经处理完前i个请求后,a在j,b在k,c在l的最小值是多少: 那么f[i][p[i]][k][l]=min(f[i][p[i]][k][l],f[i ...

  3. 字典树(trie树) 后缀树 广义后缀树

    转自:http://www.cnblogs.com/dong008259/archive/2011/11/11/2244900.html (1)字典树(Trie树) Trie是个简单但实用的数据结构, ...

  4. python3抓取中国天气网不同城市7天、15天实时数据

    思路:1.根据city.txt文档来获取不同城市code2.获取中国天气网7d和15d不同城市url3.利用requests库请求url获取html内容4.利用beautifulsoup获取7d和15 ...

  5. Appium+Python之获取toast

    思考:手机APP上的必填或错误文本提示一般1-2s就会消失,比较难定位,所以一般的固定元素定位方式是不可用的,那我们如何定位toast呢? 前提:1.Appium1.6.3以上(包括1.6.3) 2. ...

  6. Python爬虫之简单的爬取百度贴吧数据

    首先要使用的第类库有 urllib下的request  以及urllib下的parse  以及 time包  random包 之后我们定义一个名叫BaiduSpider类用来爬取信息 属性有 url: ...

  7. $().click()和$(document).on('click','要选择的元素',function(){})的不同(转https://www.cnblogs.com/sqh17/p/7746418.html)

    $(document).on();用于动态绑定事件 jQuery的出现,大大简化了对dom的操作,但是如果不是仔细阅读api和进行操作,就不知道其中最大的优点和使用方式.就拿$().click()和$ ...

  8. vue-awesome-swiper轮播插件

    1. github上搜索vue-awesome-swiper 2. readme中有安装方法,建议在插件名后@版本号,使用稳定的老版本 npm install vue-awesome-swiper@x ...

  9. atxserver2-rethinkdb的一些基础操作

    因为我只需要一些基础操作就好,所以在web端的 Data Explorer 操作,首先启动  rethinkdb.exe,然后登陆网页端, 下面是一些基础操作的语句, 一.创建表r.db(‘atxse ...

  10. WPF中的Stretch属性

    有时候我们在WPF程序中设置了图片的Width和Height,但图片显示出来的宽和高并不是我们预期的效果,这实际上是由于Image的默认Stretch属性导致的 Image的Stretch属性默认为U ...