手把手带你做一个超炫酷loading成功动画view Android自定义view

来源:互联网 发布:网络歌手小右个人 编辑:程序博客网 时间:2024/05/14 06:33

写在前面:

        本篇可能是手把手自定义view系列最后一篇了,实际上我也是一周前才开始真正接触自定义view,通过这一周的练习,基本上已经熟练自定义view,能够应对一般的view需要,那么就以本篇来结尾告一段落,搞完毕设的开题报告后去学习新的内容。

        有人对我说类似的效果网上已经有了呀,直接拿来就可以用,为什么还要写。我个人的观点是:第三方控件多数不能完全满足UI的要求,如果需要修改,那么必须理解他的实现,所以很有必要自己去写一款出来,成为程序的创造者,而不单单是使用者。所以,写一写已经实现的效果,对学习来说还是很重要的。我相信,等从使用者变成创造者之后,会有很大的提高。


每一篇博客都是建立在之前博客的基础知识上的,如果你刚接触自定义view。可以来说说自定义view简单学习的方式这里看我以前的文章。记录了我学习自定义view的过程,而且前几篇博客或多或少犯了一些错误(重复绘制,onDraw里new对象等等)。这里我并不想改正博文中的错误,因为些错误是大家经常会犯的,后来的博客都有指出这些错误,以及不再犯,这是一个学习的过程。所以我想把错误的经历记录下来。等成为高手 回头看看当年的自己是多么菜。。也会有成就感。。


转载请注明出处:http://blog.csdn.NET/wingichoy/article/details/50482271

好了,前面说的有点多。。那么开始正题,这次实现的是一个带有动画效果的loading,  难度比之前的所有文章都要复杂。但是其实一步一步分解做下来,用心去做还是不难的。

为了美观一些,我把它放到了dialog里面   上效果图: 



怎么样!是不是很炫酷,自我感觉很融入系统,像原生的东西#王婆卖瓜#


开始之前。我想说一下我的大体思路,不知道有没有更好的方法。欢迎拍砖指点交流!

对于动画效果,我全局采用一种percent,和标记位思想。也就是绘制分段,如果不达到100%,就一直画到底。如:对于一条线,从一端画到另一端,他的第二个点的坐标不断变化,我就用 最终的长度 * 百分比 来作为过度时期的变量, 即canvas.drawLine(0,0,x * percent /100,y * percent /100);    标记位的话就一一个boolean值,如果来判断该怎么画。 缺点也很明显:每次都要if 他percent到没到100%  嵌套太多次,不知道有没有解决办法。


现在来分析一下动画的过程。基础的坐标计算一下就好,这里就不多说,如果你这些还不熟练,你可以看看我之前的文章:手把手带你绘制一个时尚仪表盘

1.首先要做的是绘制出来刚开始静态的圆和箭头, 箭头用path画。

2.是竖线缩短的过程,变成一个点。

3.箭头变横线。

4.点被横线抛出到圆。

5.按百分比绘制的弧,同时直线变对勾。

之后我们就一个一个来画。构造函数测量的就省去了。


那么 拿起你的paint 开始跟我一起draw吧

初始化一下画笔

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. Paint p = new Paint();  
  2.   
  3.        Path path = new Path();  
  4.        p.setColor(Color.parseColor("#2EA4F2"));  
  5.        p.setStyle(Paint.Style.STROKE);  
  6.        p.setStrokeWidth(8);  
  7.        p.setAntiAlias(true);  
  8.   
  9.        //百分比弧的矩形  
  10.        RectF rectF = new RectF(55, mWidth - 5, mHeight - 5);  
  11.   
  12.        //绘制圆  
  13.        canvas.drawCircle(mWidth / 2, mHeight / 2, mWidth / 2 - 5, p);  
这里设置一个标志位,用于标记是否可以开始绘制动画。
[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. if (canStartDraw) {  
  2.     isDrawing = true;  

如果不可以,则绘制静态的箭头。

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. else {  
  2.             //绘制静态箭头  
  3.             p.setColor(Color.WHITE);  
  4.             canvas.drawLine(mWidth / 2, mHeight / 4, mWidth / 2, mHeight * 0.75f, p);  
  5. //            Path path = new Path();  
  6.             path.moveTo(mWidth / 4, mHeight * 0.5f);  
  7.             path.lineTo(mWidth / 2, mHeight * 0.75f);  
  8.             path.lineTo(mWidth * 0.75f, mHeight * 0.5f);  
  9.             canvas.drawPath(path, p);  
  10.         }  
现在的效果是这样的

2.线变成一个点。 这里的效果其实就是不断绘制一个线,基本上坐标的变化可以用如下表示:   x,y1+percent,x,y2-percent.

那么这里就开始drawLine   用百分比控制具体的变化量。   这里为什么percent 不自增到100呢,原因是线最终要缩短成和点一样的大小,并非消失。这里就完成了第一阶段的动画。

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. isDrawing = true;  
  2.            //开始变形  
  3.            p.setColor(Color.WHITE);  
  4.   
  5.            //如果小于95 就继续缩短。 95是微调值 和point大小相等  
  6.            if (mLineShrinkPercent < 95) {  
  7.                //线段逐渐缩短(终点为mWidth/2,mHeight/2)  
  8.                float tmp = (mWidth / 2 - mHeight / 4) * mLineShrinkPercent / 100;  
  9.                canvas.drawLine(mWidth / 2, mHeight / 4 + tmp, mWidth / 2, mHeight * 0.75f - tmp, p);  
  10.                mLineShrinkPercent += 5;  
  11.            } else {  


3.箭头变横线   由于箭头是Path画的,所以我们只要改变path中间那个点的y坐标就可以了。 这里需要注意的是 在变成西线的过程中,点是一直存在的,所以要画一个circle上去(为什么不point,因为他很方= =),也是用一个百分比来控制。

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. //path变成直线  
  2.                 isPathToLine = true;  
  3.                 if (mPathPercent < 100) {  
  4.   
  5.                     path.moveTo(mWidth / 4, mHeight * 0.5f);  
  6.                     path.lineTo(mWidth / 2, mHeight * 0.75f - mPathPercent / 100f * 0.25f * mHeight);  
  7.                     path.lineTo(mWidth * 0.75f, mHeight * 0.5f);  
  8.                     canvas.drawPath(path, p);  
  9.                     mPathPercent += 5;  
  10.   
  11.                     //在变成直线的过程中这个点一直存在  
  12.                     canvas.drawCircle(mWidth / 2, mHeight / 2,2.5f, p);  
  13.                 } else {  

4.点被横线抛出到圆弧上,同样也是百分比控制。   最终的圆心坐标为 mWidth/2,0

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. //绘制把点上弹的直线  
  2.   
  3.                     //画上升的点  
  4.                     if (mRisePercent < 100) {  
  5.   
  6.                         //在点移动到圆弧上的时候 线是一直存在的  
  7.                         canvas.drawLine(mWidth / 4, mHeight * 0.5f, mWidth * 0.75f, mHeight * 0.5f, p);  
  8.   
  9.                         canvas.drawCircle(mWidth / 2, mHeight / 2 - mHeight / 2 * mRisePercent / 100 + 5,2.5f, p);  
  10.   
  11.                         mRisePercent += 5;  
  12.                     } else  

5.按百分比绘制的弧,同时直线变对勾。 弧的话,注意一下起始弧度是270, 绘制弧度为360*percent就可以。对勾跟上面一样,因为本身是一条Path,这次同时改变第二个点和第三个点就可以了。

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. //上升的点最终的位置  
  2.                         canvas.drawPoint(mWidth / 25, p);  
  3.                         isRiseDone = true;  
  4.   
  5.                         //改变对勾形状  
  6.                         if (mLinePercent < 100) {  
  7.   
  8.                             path.moveTo(mWidth / 4, mHeight * 0.5f);  
  9.                             path.lineTo(mWidth / 2, mHeight * 0.5f+ mLinePercent/100f * mHeight * 0.25f);  
  10.                             path.lineTo(mWidth * 0.75f, mHeight * 0.5f - mLinePercent / 100f * mHeight * 0.3f);  
  11.                             canvas.drawPath(path, p);  
  12.                             mLinePercent += 5;  
  13.   
  14.                             //动态绘制圆形百分比  
  15.                             if (mCirclePercent < 100) {  
  16.                                 canvas.drawArc(rectF, 270, -mCirclePercent / 100.0f * 360false, p);  
  17.                                 mCirclePercent += 5;  
  18.                             }  

6.(为什么有6??) 很重要的一点,切忌不要忘记。如果你只写了以上代码,你运行完会发现所有绘图都消失了! 那是因为percent超过100就不进行绘制了,所以在最外面的else里需要绘制一个圆加一个对号。完成之后直接  postInvalidateDelayed(10);

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <pre name="code" class="java">else {  
  2.                             //绘制最终的path  
  3.                             path.moveTo(mWidth / 4, mHeight * 0.5f);  
  4.                             path.lineTo(mWidth / 2, mHeight * 0.75f);  
  5.                             path.lineTo(mWidth * 0.75f, mHeight * 0.3f);  
  6.                             canvas.drawPath(path, p);  
  7. //                            绘制最终的圆  
  8.                             canvas.drawArc(rectF, 270, -360false, p);  
  9.   
  10.                             isDrawing = false;  
  11.   
  12.                         }  


7.(还有7,你逗我?)加一个start方法 用于重置各种标记位

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public void start() {  
  2.       if (isDrawing == false) {  
  3.           canStartDraw = true;  
  4.           isRiseDone = false;  
  5.           mRisePercent = 0;  
  6.           mLineShrinkPercent = 0;  
  7.           mCirclePercent = 0;  
  8.           mPathPercent = 0;  
  9.           mLinePercent = 0;  
  10.           invalidate();  
  11.       }  
  12.   }  


之后就大功告成了!!!


本项目地址: 点击打开链接   求关注  求评论  求star    那么,手把手带你写view系列就基本完结了。

手把手番外篇: 手把手教你画一个 逼格满满圆形水波纹loadingview Android

0 0
原创粉丝点击