自定义LoadingView大全之转动立方体
2016-07-06 22:51
218 查看
回声的千结百绕
而守候的是
执着
一仓央嘉措
上图吧:
![](https://img-blog.csdn.net/20160706191150569)
第一次看到这样的效果,是不是让你眼前一亮,格逼一下就上去了。你可能会问,实现起来会不会很难啊,可以明确的说实现不难,需要你有足够的耐心。
![](https://img-blog.csdn.net/20160706215534963)
先来看看大的立方体,它是由9个面组成,分成了三个阶段。
第一阶段:从A运动到B
数字标出1,2,3,4,5左上运动,每个点的X,Y都在减少;6,7,8,9右下运动,每个点的X,Y坐标都在增大。左右两边长的立方体总共运动了菱形的一个边长,那么可以知道每个长的立方体运动了边长的二分之一。
第二阶段:从B运动到C
1,2面右上运动,每个点的X坐标增大,Y减少;3,4,5,6面没有运动;7,8,9面左下运动,X坐标减少,Y增大。如果把1,2面看成一个立方体则运动了一个菱形的边长。7,8,9面同理。
第三阶段:从C运动到A
3,4,5,7,8,9面左上运动X,Y坐标都在减少;1,2,6面右下运动X,Y都在增大且运动了半个菱形的边长。
比较复杂的是需要去绘制大的立方体A,可以把A分离成9个面,绘制每个面,那么我们先来分析一个面:
![](https://img-blog.csdn.net/20160706200707215)
设定a为30°,对应的三角形高度为h,那么另一条长度为√3h(根号)。
把A画到坐标系上,如图:
![](https://img-blog.csdn.net/20160706222523161)
这样是不是就很明了,我们只需要知道中心点坐标,h的长度就可以画出A(大的立方体)。OK,只要画出A,后面的就简单了。
在ondraw方法中处理不同阶段的绘制:
mValueAnimator 取值(0.0f~1.0f);mShadow是否显示阴影。
第一阶段绘制:
在代码中我对每个面的变化都有相应的注释,应该都是可以看懂的。
绘制一个立方体效果图:
![](https://img-blog.csdn.net/20160706224345375)
能够绘制立方体的变化,阴影层的绘制就非常简单了。
源码地址,如果你喜欢就给我star,再次感谢大家的关注。
自定义LoadingView大全
而守候的是
执着
一仓央嘉措
概述
这篇是自定义LoadingView大全的第四篇博客,也是写得最累最费心费脑的一篇博客,我现在眼睛还疲惫的难受。作为一名程序猿,我在表达能力方面比较欠缺,我希望我能够把它讲清楚。在讲解的过程当中我都会配以图片加以说明。上图吧:
第一次看到这样的效果,是不是让你眼前一亮,格逼一下就上去了。你可能会问,实现起来会不会很难啊,可以明确的说实现不难,需要你有足够的耐心。
具体实现
分析
在开始动手写代码之前,我习惯会去先分析转动的立方体该怎么去绘制和添加动画。先来看看下面这张示意图:先来看看大的立方体,它是由9个面组成,分成了三个阶段。
第一阶段:从A运动到B
数字标出1,2,3,4,5左上运动,每个点的X,Y都在减少;6,7,8,9右下运动,每个点的X,Y坐标都在增大。左右两边长的立方体总共运动了菱形的一个边长,那么可以知道每个长的立方体运动了边长的二分之一。
第二阶段:从B运动到C
1,2面右上运动,每个点的X坐标增大,Y减少;3,4,5,6面没有运动;7,8,9面左下运动,X坐标减少,Y增大。如果把1,2面看成一个立方体则运动了一个菱形的边长。7,8,9面同理。
第三阶段:从C运动到A
3,4,5,7,8,9面左上运动X,Y坐标都在减少;1,2,6面右下运动X,Y都在增大且运动了半个菱形的边长。
比较复杂的是需要去绘制大的立方体A,可以把A分离成9个面,绘制每个面,那么我们先来分析一个面:
设定a为30°,对应的三角形高度为h,那么另一条长度为√3h(根号)。
把A画到坐标系上,如图:
这样是不是就很明了,我们只需要知道中心点坐标,h的长度就可以画出A(大的立方体)。OK,只要画出A,后面的就简单了。
编码
获取中心点坐标以及h的长度:centerX = w / 2; mWidth = Math.min(w, h); //平行四边形的最小角度为30度 mItemWidth = mWidth / 16 * (float) Math.sqrt(3); mItemHeight = mWidth / 16;
在ondraw方法中处理不同阶段的绘制:
if (mValueAnimator >= 0 && mValueAnimator < (1.0f / 3)) { //绘制第一阶段 drawStage1(canvas, mValueAnimator); if (mShadow) { drawShadow1(canvas, mValueAnimator); } } else if (mValueAnimator >= (1.0f / 3) && mValueAnimator < (1.0f / 3 * 2)) { //绘制第二阶段 drawStage2(canvas, mValueAnimator); if (mShadow) { drawShadow2(canvas, mValueAnimator); } } else if (mValueAnimator >= (1.0f / 3 * 2) && mValueAnimator <= 1.0f) { //绘制第三阶段 drawStage3(canvas, mValueAnimator); if (mShadow) { drawShadow3(canvas, mValueAnimator); } }
mValueAnimator 取值(0.0f~1.0f);mShadow是否显示阴影。
第一阶段绘制:
//这里2个立方体都在移动,每个立方体在X轴方向移动的距离为mItemWidth/2 float moveX = mItemWidth / 2.0f * valueAnimator / (1.0f / 3); float moveY = mItemHeight / 2.0f * valueAnimator / (1.0f / 3); //顺时针绘制平行四边形 //向后移动在X 方向 减少 Y方向减少 Path p = new Path(); p.moveTo(centerX - 2 * mItemWidth - moveX, 4 * mItemHeight - moveY); p.lineTo(centerX - mItemWidth - moveX, 3 * mItemHeight - moveY); p.lineTo(centerX - moveX, 4 * mItemHeight - moveY); p.lineTo(centerX - mItemWidth - moveX, 5 * mItemHeight - moveY); p.close(); canvas.drawPath(p, mPaint); //向后移动在X 方向 减少 Y方向减少 p.reset(); p.moveTo(centerX - 2 * mItemWidth - moveX, 4 * mItemHeight - moveY); p.lineTo(centerX - mItemWidth - moveX, 5 * mItemHeight - moveY); p.lineTo(centerX - mItemWidth - moveX, 7 * mItemHeight - moveY); p.lineTo(centerX - 2 * mItemWidth - moveX, 6 * mItemHeight - moveY); p.close(); canvas.drawPath(p, mPaintLeft); //向前移动在X 方向 X方向增加 Y方向增加 p.reset(); p.moveTo(centerX + moveX, 4 * mItemHeight + moveY); p.lineTo(centerX - mItemWidth + moveX, 3 * mItemHeight + moveY); p.lineTo(centerX + moveX, 2 * mItemHeight + moveY); p.lineTo(centerX + mItemWidth + moveX, 3 * mItemHeight + moveY); p.close(); canvas.drawPath(p, mPaint); //向前移动在X 方向 X方向增加 Y方向增加 p.reset(); p.moveTo(centerX + moveX, 4 * mItemHeight + moveY); p.lineTo(centerX + mItemWidth + moveX, 3 * mItemHeight + moveY); p.lineTo(centerX + 2 * mItemWidth + moveX, 4 * mItemHeight + moveY); p.lineTo(centerX + mItemWidth + moveX, 5 * mItemHeight + moveY); p.close(); canvas.drawPath(p, mPaint); //向前移动在X 方向 X方向增加 Y方向增加 p.reset(); p.moveTo(centerX + moveX, 4 * mItemHeight + moveY); p.lineTo(centerX + mItemWidth + moveX, 5 * mItemHeight + moveY); p.lineTo(centerX + mItemWidth + moveX, 7 * mItemHeight + moveY); p.lineTo(centerX + moveX, 6 * mItemHeight + moveY); p.close(); canvas.drawPath(p, mPaintLeft); //向前移动在X 方向 X方向增加 Y方向增加 p.reset(); p.moveTo(centerX + mItemWidth + moveX, 5 * mItemHeight + moveY); p.lineTo(centerX + 2 * mItemWidth + moveX, 4 * mItemHeight + moveY); p.lineTo(centerX + 2 * mItemWidth + moveX, 6 * mItemHeight + moveY); p.lineTo(centerX + mItemWidth + moveX, 7 * mItemHeight + moveY); p.close(); canvas.drawPath(p, mPaintRight); //向后移动在X 方向 减少 Y方向减少 p.reset(); p.moveTo(centerX - mItemWidth - moveX, 5 * mItemHeight - moveY); p.lineTo(centerX - moveX, 4 * mItemHeight - moveY); p.lineTo(centerX + mItemWidth - moveX, 5 * mItemHeight - moveY); p.lineTo(centerX - moveX, 6 * mItemHeight - moveY); p.close(); canvas.drawPath(p, mPaint); //向后移动在X 方向 减少 Y方向减少 p.reset(); p.moveTo(centerX - mItemWidth - moveX, 5 * mItemHeight - moveY); p.lineTo(centerX - moveX, 6 * mItemHeight - moveY); p.lineTo(centerX - moveX, 8 * mItemHeight - moveY); p.lineTo(centerX - mItemWidth - moveX, 7 * mItemHeight - moveY); p.close(); canvas.drawPath(p, mPaintLeft); //向后移动在X 方向 减少 Y方向减少 p.reset(); p.moveTo(centerX - moveX, 6 * mItemHeight - moveY); p.lineTo(centerX + mItemWidth - moveX, 5 * mItemHeight - moveY); p.lineTo(centerX + mItemWidth - moveX, 7 * mItemHeight - moveY); p.lineTo(centerX - moveX, 8 * mItemHeight - moveY); p.close(); canvas.drawPath(p, mPaintRight);
在代码中我对每个面的变化都有相应的注释,应该都是可以看懂的。
绘制一个立方体效果图:
能够绘制立方体的变化,阴影层的绘制就非常简单了。
源码地址,如果你喜欢就给我star,再次感谢大家的关注。
自定义LoadingView大全
相关文章推荐
- 面试题31:连续子数组的最大和
- Codeforces Round #355 (Div. 2)D. Vanya and Treasure
- UIMenuController和UIMenuItem的使用
- Java-JDBC调用批处理、存储过程、事务
- cocos2d-x 中box2d的简单使用,代码来自传智播客c++课程 。
- SeaJS前段模块化编程学习2
- 【C/C++】深入位运算之比赛顺序
- poj 3784 Running Median
- 事件CEvent的使用
- CSS3 box-reflect(倒影效果)
- C++中对象作为函数形参,返回值时,构造函数,复制构造函数,析构函数的调用顺序(1)
- Codeforces 622C Not Equal on a Segment 【线段树 Or DP】
- Codeforces 622C Not Equal on a Segment 【线段树 Or DP】
- java问题整理
- Codeforces 622C Not Equal on a Segment 【线段树 Or DP】
- c语言学习笔记47
- ORA-00600: internal error code, arguments: [kcratr1_lastbwr], [], [], [], [], [], [], []
- 上传代码到GitHub时,遇到错误:fatal,The Requested URL return error 403
- 《这本书能让你戒烟》:野路子戒烟法。也许读者是否戒烟成功已经不重要了,重要的是这本书的销售非常成功。三星推荐
- PHP 精确验证身份证号