android自定义view 模仿win10进度条


转载地址:http://blog.csdn.net/zhangml0522/article/details/52556418#t5


先上预览图:

流程

  • 1.一个匀速圆周运动的点
  • 2.多个匀速圆周运动的点
  • 3.多个圆周运动的点,速度由快到慢
  • 4.点与点之间的间距线性减少,动画的最后合为一个点
  • 5.为了让动画看起来更加流畅,需要在动画即将结束的时候手动绘制点

核心控件

  • PathMeasure:截取Path中的一部分并显示
  • ValueAnimator:完成动画从初始值平滑的过度到结束值的效果,同时还负责管理动画的播放次数、播放模式、以及对动画设置监听器等

流程一

思路

  1. 先用path画一个圆
  2. ValueAnimator设置为0f-1f的平滑
  3. 用PathMeasure根据ValueAnimator返回的值截取path上的一个点

这里的ValueAnimator设置的是一个时长3秒的动画,再这3秒中,ValueAnimator会返回一个由0f-1f平滑的数字 
ValueAnimator.ofFloat(0f,1f).setDuration(3000) 
在这里我们用t来接受返回值,同时刷新视图

<code class="hljs fix has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-attribute" style="box-sizing: border-box;">t </span>=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;"> (float) animation.getAnimatedValue();
invalidate();</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

 
这里可以看出t的值,有0到1,这里就可以把t理解为我们这个动画的进度

  • 开始绘制

  • 结果图: 

流程二

思路

  • 我们设置让t每间隔0.05就画一个点,总共画4个点,注意这里getSegment()的最后一个要设置为true来保证画出来的是多个点而不是一条线

  • 结果图 

流程三

思路

我们先绘制出路程-时间的函数图像 
 
函数为y = -x*x + 2*x,当x=1时,y=mPathMeasure.getLength(); 
设s = mPathMeasure.getLength(); 
最终我们套用函数:y = -s*x*x+2*s*x; 
这里的Y轴代表的是path的长度,X轴对应时间 
所以把流程二中的y = s*x改成y = -s*x*x+2*s*x即可


  • 结果图 

流程四

思路

虽然流程3中点与点的间距已经开始减少,不过这只是因为速度不同间距才改变的,我们的目的是让这些点到最后合并为1个点,也就是说开始的时候每个点的X间距0.05,结束的时候要让他们的X相同 
目前点之间X的间距函数如下: 
 
我们最后要让当X=1时,他们的Y值相等,而且他们X的间距由0.05线性平滑到0 
 
看函数图像已经很清楚了,修改后代码如下:


  • 结果图 

流程五

思路

这里已经完成了99.9%了,但细心的同学会发现,进度条每次转动一圈聚成一个点后都会闪一下,这是因为重新开始动画刷新视图的原因,这里的补救方法就是我们在动画快结束的时候手动画一个点

<code class="hljs mel has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(t>=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.95</span>){
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">canvas</span>.drawPoint(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">150</span>,mPaint);
        }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

这样我们就完成了这个进度条 
 


你可能感兴趣的:(android,动画,自定义进度条)