Android自定义View炫酷的剑气加载效果实现
看到一个非常炫的加载效果,文章中大佬是通过css实现的,今天咱们来用Android的自定义View来实现一下这是理想中的效果
这是现实的效果
不能说百分百还原吧,只能说精髓
开工
这个效果仔细看,就是有三个类似月牙形状的元素进行循环转动,我们只需要拆解出一个月牙来做效果即可,最后再将三个月牙组合起来就可以达到最终效果了月牙
先画一个圆
再画个大一丢丢的
再把这个大圆往右移一丢丢,裁切出来的左右两个都是月牙
实现
老司机应该一眼就能看出来,只要在两次绘制圆中只要使用一个叠加模式就能达到裁剪出一个月牙的效果了。那么是什么模式呢,我去搜索一下
当当当,就是它PorterDuff。Mode。DSTOUT
相关源码如下:canvas。drawColor(Color。BLACK)vallayerIdcanvas。saveLayer(0f,0f,width。toFloat(),height。toFloat(),null,Canvas。ALLSAVEFLAG)valhalfWwidth2fvalhalfHheight2fvalradiusmin(width,height)3fpaint。colorColor。WHITEcanvas。drawCircle(halfW,halfH,radius,paint)paint。colorColor。BLACKpaint。xfermodexfermodecanvas。drawCircle(halfW,halfH0。05fradius,radius1。01f,paint)canvas。restoreToCount(layerId)paint。xfermodenull
运行起来我们就得到了一弯浅浅的月牙
立体空间变化
我们可以看出效果图里的每一个月牙并不是那么方正,而是有一定的空间旋转,再加上绕着Z轴旋转。这里需要利用Camera与Matrix实现3D效果(相关知识可参考:https:www。jianshu。comp34e0fe5f9e31)
我们先给它在x轴转35度,y轴转45度(参考开头文章的数据)rotateMatrix。reset()camera。save()camera。rotateX(35F)camera。rotateY(45F)camera。getMatrix(rotateMatrix)camera。restore()valhalfWwidth2fvalhalfHheight2frotateMatrix。preTranslate(halfW,halfH)rotateMatrix。postTranslate(halfW,halfH)canvas。concat(rotateMatrix)
运行效果如下,从普通的月牙变成了帅气的剑气
动画
我们上面做了固定角度的X,Y轴的旋转,这个时候我们只要加上一个Z轴的调转动画,这个剑气就动起来了。valanimValueAnimator。ofFloat(0f,360f)。apply{Z轴是逆时针,取负数,得到顺时针的旋转interpolatornullrepeatCountRotateAnimation。INFINITEduration1000addUpdateListener{invalidate()}}省略前面已写代码。。。camera。rotateZ(anim。animatedValueasFloat)在合适的地方启动动画view。anim。start()
运行效果:
举一反三
有了这一个完整的剑气旋转,只要再来两道,组成完整的剑气加载就可以了。
将前面的代码抽象成一个方法privatefundrawSword(canvas:Canvas,rotateX:Float,rotateY:Float){vallayerIdcanvas。saveLayer(0f,0f,width。toFloat(),height。toFloat(),null,Canvas。ALLSAVEFLAG)rotateMatrix。reset()camera。save()camera。rotateX(rotateX)camera。rotateY(rotateY)camera。rotateZ(anim。animatedValueasFloat)camera。getMatrix(rotateMatrix)camera。restore()valhalfWwidth2fvalhalfHheight2frotateMatrix。preTranslate(halfW,halfH)rotateMatrix。postTranslate(halfW,halfH)canvas。concat(rotateMatrix)canvas。drawCircle(halfW,halfH,radius,paint)paint。xfermodexfermodecanvas。drawCircle(halfW,halfH0。05fradius,radius1。01f,paint)canvas。restoreToCount(layerId)paint。xfermodenull}
绘制三道剑气verridefunonDraw(canvas:Canvas){super。onDraw(canvas)canvas。drawColor(Color。BLACK)偏移角度来源开关文章drawSword(canvas,35f,45f)drawSword(canvas,50f,10f)drawSword(canvas,35f,55f)}
跑起来看看
Emm。。。这动画也太整齐划一了
错开三道剑气
在Z轴旋转上,我们给每道剑气一个初始值的旋转值(3603120),这样它们就能均匀的错开了。
相关实现如下:privatefundrawSword(canvas:Canvas,rotateX:Float,rotateY:Float,startValue:Float){。。。省略未改动代码camera。rotateZ(anim。animatedValueasFloatstartValue)。。。省略未改动代码}overridefunonDraw(canvas:Canvas){super。onDraw(canvas)canvas。drawColor(Color。BLACK)drawSword(canvas,35f,45f,0f)drawSword(canvas,50f,10f,120f)drawSword(canvas,35f,55f,240f)}
最终效果
和我们开头预期的效果图一模一样
完整代码:https:github。comsamwangdsDemoFactoryblobmasterappsrcmainjavademocomsamdemofactoryviewSwordLoadingView。kt最后
在这里还分享一份由大佬亲自收录整理的学习PDF架构视频面试文档源码笔记,高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料
这些都是我现在闲暇时还会反复翻阅的精品资料。里面对近几年的大厂面试高频知识点都有详细的讲解。相信可以有效地帮助大家掌握知识、理解原理,帮助大家在未来取得一份不错的答卷。
当然,你也可以拿去查漏补缺,提升自身的竞争力。
真心希望可以帮助到大家,Android路漫漫,共勉!
如果你有需要的话,只需私信我【进阶】即可获取