高仿小米视频加载动画效果

今日科技快讯

8月30日,格力电器公布了2017年半年度报告。2017年上半年,格力电器实现营业收入691.85亿元,同比增长40.67%,实现归属于上市公司股东的净利润94.52亿元,同比增长47.64%。其中,作为格力主营业务的空调业务营收为546.37亿元,同比增长30.14%,毛利率为38.46%,同比减少1.89%。

作者简介

又到了周五,安排充实周末生活的同时别忘了做好这一周的整理工作!提前祝大家周末愉快。

本篇来自 俊司达也 的投稿,分享了一个小米视频加载动画的效果,希望大家喜欢!

俊司达也 的博客地址:

http://blog.csdn.net/u013094278

概述

前几日出差,每晚回到酒店的时候,睡前打发时间就是拿起自己的小米手机撸剧,酒店的wifi 网络实在太差,眼睁睁的看着小米视频的加载动画一直拼命的 loading 中,正好最近一直在看自定义 view 的东西,何不乘此撸一个山寨的小米视频动画练练手,废话不多说了,先上效果图。

原理分析

总体结构分析

如上图所示,动画主要由四个三角形构成,对四个三角形进行标号,其中中间的三角形为 1号,外围顺时针方向依次为 2、3、4 号。该图形的巧妙之处在于四个三角形整体又组合为一个新的大三角形。根据上文的预览动画可以看出,四个三角形是依次出现和消失的,四个三角形出现的顺序正好是按照编号 1-2-3-4 出现的,消失的顺序是按照 4-2-3-1(不是 4-3-2-1)。

三角形的出现形式

顾名思义,只要知道三角形的三个顶点,即可以绘制出对应的三角形来。动画中三角形的绘制有个渐变过程,三角形的出现不是一蹴而就的,这里以上文中的1号三角形为例进行说明,废话不多说,直接上图:

如上图,三角形在加载的过程中,会以其中一个顶点开始,向其他两个顶点进行延伸扩展。我们这里把延伸的起点称为 start,延伸中的两个顶点分别是 current1 和 current2,延伸的终点称为 end1 和 end2,演变的过程很简单,即start点保持不变,其余两个顶点分别从 start 点向 end 点延伸。

代码实现

说了这么多,可以着手开始撸代码了。既然我们的动画都是以三角形为单元的,所以我们可以定义一个三角形类 TriangleView,这个类至少包含如下几个属性:

  • 三角形的三个顶点坐标,即上文分析中提到的 start、end1、end2 坐标;

  • 三角形的背景色;

  • 三角形目前加载过程中 current1 和 current2 的坐标位置;

代码很简单,仅仅是我们上述所描述的属性,起点坐标、终点坐标、延伸中的当前坐标和背景色。

下面自定义我们的 View,我这里起名为 MyVideoView,代码如下:

如上代码,注释已经很清楚了,相信你们都可以看明白,需要说明的是,因为我们的动画是由四个三角形构成,所以我们用 TriangleView 数组来进行存放,存放的顺序按照上文中的 1-2-3-4 号三角形存放,即三角形的出现顺序。另外,为了让程序在特定的时间点知道应当绘制哪一个三角形,设置一个枚举变量来存放当前应当绘制的状态。枚举变量的含义这里简单说下,XXXX_LOADING 表示是第几个三角形正在展现,例如 MID_LOADING 表示中间的三角形开始绘制,XXXX_DISMISS 表示第几个三角形正在消失,LOADING_COMPLETE 表示四个三角形全部展现完毕,需要在这个状态下停留一段时间。

在 onMeasure 的时候,除了获取控件的中心点坐标以为,还需要对四个三角形的坐标进行初始化,首先需要确定的就是1号三角形,即中间三角形的位置,为了进一步说明坐标的计算,示意图如下所示:

如上图是中间三角形的示意图,三个顶点我们记为 A、B、C,根据最终三角形的构造来看,中间三角形的中心点E为控件的中心点,即上述代码中的 CvX 和 CvY,我们需要通过中心点 CvX 和 CvY,即 E 点,求出 A、B、C点的坐标,三角形是一个等边三角形,同时边长 Edge 是已知的,所以要求出线段 AD、DB、ED、CE 的长度就可以计算出 A、B、C 点三点的坐标。由于 AD、DB 正好是二分之一的边长,所以也是已知的,E是中心点,所以 ED和 CE 的长度一样,所以关键只要求出 CD 的值就可以了,而三角形 BCD 又是一个直角三角形,CD 是直角边,根据勾股定理,可以求出 CD 的值,CD 的长度为 BC 的平方 -DB 的平方再开方即可(这里吐槽一下,初中的几何知识较多)

废话又太多了,上代码:

相信上面说了那么多,这块代码应当很容易理解,在纸上把四个三角形的相对位置绘制出来,坐标位置便一目了然。

三角形的具体绘制放到 onDraw 中,代码如下:

onDraw 的方法是对三角形的实际绘制,代码量没有几行,原理也很简单,只是将三角形数组 triangles 中的三角形对象取出来分别进行绘制。这里有个简单的处理,即如果当前的绘制状态是 MID_LOADING 的时候,即最开始绘制中间三角形的时候,其他三角形没有必要绘制了,通过 break 跳出循环。

动画的制作最为关键的就是插值,在绘图的过程中不停的改变绘制的变量来达到动画形变的效果,好了继续粘贴动画插值的代码,这里代码过长,有兴趣的同学可以阅读原文去查看。

上述代码中需要对动画的循环 onAnimationRepeat 进行监听,每次循环会更改一次动画状态,例如每次循环会绘制一个三角形或者消失一个三角形,然后对 onAnimationUpdate 进行监听,这里需要注意的是,如果目前的动画效果是要显示三角形,则提取到的 fraction 应当为从 0 到 1 的渐变过程,如果动画效果是消失一个三角形,则 fraction 应当是从1到0的渐变过程,所以代码中有一句 1-fraction 的操作。current 的值初始是在 start 位置上,随着 fraction 的演进,current 的值需要在 start 的基础上增加对应的演进过程,演进的变化量就是 fraction 乘以 start 与 end 节点之间的距离。

细心的同学或许已经发现在上述代码的第 56 行调用了 reverseTriangleStart 方法,这个方法有什么用呢,如果大家再回头本文的开头部分观察动画的演示效果的话,细心一点会发现,三角形出现的时候起始点的位置和三角形消失的时候起始点的位置是不同的,即原来的起始点在三角形消失的时候是作为 end 点进行的,而原来的其中一个 end 点变成了 start点,这个动画的巧妙之处就在于看似有规律的三角形绘制顺序,其实并不是按照既定的规则来的,而且三角形消失的顺序与三角形出现的顺序是不一致的。所以我们的枚举变量中在 THIRD_DISMISS 之后是 FIRST_DISMISS,并不是 SECONDE_DISMISS 。好了下面继续粘贴代码:

代码很简单,仅仅是交换每个三角形 start 和 end1 的值,让之前的 end1 变成了新的 start顶点,这里需要注意的是,current 的值应当与 end1 的值保持一致。否则在 onDraw 中,当处于 LOADING_COMPLETE 状态下,由于 start 与 end1 的值进行了交换,current 的值还是按照之前的来会出现问题,大家可以手动调试下就知道了。

结语

本工程主要传递该动画的制作思路,还有些地方并不完善,例如没有把属性自定义抽取出来,onMeasure 没有针对自适应进行重构等,第一篇博文欢迎各位拍砖。

项目地址:

https://github.com/wangjinfeng-junsidaye/MiVideoLoadView

更多

每天学习累了,看些搞笑的段子放松一下吧。关注最具娱乐精神的公众号,每天都有好心情。

如果你有好的技术文章想和大家分享,欢迎向我的公众号投稿,投稿具体细节请在公众号主页点击“投稿”菜单查看。

欢迎长按下图 -> 识别图中二维码或者扫一扫关注我的公众号:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值