- 本文已受权微信公众号: 鸿洋 (hongyangAndroid) 原创首发
最近把公司智能家具类的应用中的一个负离子净化显示的控件重写了,干脆就封装了一下起个高大上的名字空气净化器控件,感受比负离子净化牛逼一点,好像最近锤子也发布了一个空气净化器。java
一共才写了几个篇博客,没经验啊,看了下别人的都写原理什么的,此次就写一下里面至关比较复杂的效果的,其实,,,,没什么复杂的,不知道从何提及捡几个用于的说。git
- 1. 改变上中下字体大小,字体信息
- 2. 背景颜色实现渐变切换
- 3. 实现扇叶无缝开启和关闭,从上次结束的位置开始动画
- 4. 实现颗粒物效果
- 5. 无缝改变扇叶的速度
- 6.实现扇叶的渐变显示,更加真实
扇叶对比github
// kotlin版 java也是同样就是设置一下绘制效果就能够绘制虚线圆
val pathEffect = DashPathEffect(floatArrayOf(mPaint.strokeWidth*0.4f,mPaint.strokeWidth),0f)
mPaint.pathEffect = pathEffect
canvas.drawCircle(dashedRingCx,dashedRingCy,dashedRingRadius,mPaint)
复制代码
// kotlin版 java也是同样
//实现渐变扇叶
while (curAngle < 360 - mEachPanAngle) {
val x0 = measuredWidth/2f + (Math.cos((curAngle)*Math.PI/180)*(dashedRingRadius-dashedRadiusDiff*0.5)).toFloat()
val y0 = measuredHeight/2f + (Math.sin((curAngle)*Math.PI/180)*(dashedRingRadius-dashedRadiusDiff*0.5)).toFloat()
val x1 = measuredWidth/2f + (Math.cos((curAngle+mEachPanAngle)*Math.PI/180)*(dashedRingRadius+dashedRadiusDiff*0.5)).toFloat()
val y1 = measuredHeight/2f + (Math.sin((curAngle+mEachPanAngle)*Math.PI/180)*(dashedRingRadius+dashedRadiusDiff*0.5)).toFloat()
val shader = LinearGradient(x0, y0, x1, y1, Color.parseColor("#22ffffff"), Color.parseColor("#ffffffff"), Shader.TileMode.CLAMP)
mPaint.shader = shader
canvas?.drawArc(rectF, curAngle, mEachPanAngle, false, mPaint)
curAngle = curAngle + mEachPanAngle + mEachPanAngleGap
}
mPaint.shader = null //记得清除
复制代码
这个的实现方法就不少了能够直接属性动画一个起始值一个结束值,设置animator.setEvaluator(ArgbEvaluator()),还有一个就是使用Hsv 使颜色渐变动适合人类观感,公式就不写,网上有源码里也有。canvas
这个动画仍是使用属性动画,但注意每次开启和关闭时传入的值,当前值为起始值,结束值为你要到的值,代码其实很简单。 微信
private fun onFanAnim(isOpenFan: Boolean) {
if (mJumpAnimator != null && mJumpAnimator!!.isRunning) {
mJumpAnimator!!.cancel()
}
if (isOpenFan) {
mJumpAnimator = ObjectAnimator.ofFloat(this,"dashedRadiusDiff",dashedRadiusDiff,mDashedRingWidth)
mJumpAnimator!!.interpolator = DecelerateInterpolator()
mJumpAnimator!!.addListener(object : Animator.AnimatorListener{
override fun onAnimationRepeat(p0: Animator?) {
}
override fun onAnimationEnd(p0: Animator?) {
if (!isCancelJumpAnim) {
mPanListener?.onHasOpen()
onRotateAnim()
}
isCancelJumpAnim = false
}
override fun onAnimationCancel(p0: Animator?) {
isCancelJumpAnim = true
}
override fun onAnimationStart(p0: Animator?) {
}
})
mJumpAnimator!!.duration = 2000
} else {
mJumpAnimator = ObjectAnimator.ofFloat(this,"dashedRadiusDiff",dashedRadiusDiff,0f)
mJumpAnimator!!.interpolator = AccelerateInterpolator()
mJumpAnimator!!.addListener(object : Animator.AnimatorListener{
override fun onAnimationRepeat(p0: Animator?) {
}
override fun onAnimationEnd(p0: Animator?) {
if (dashedRadiusDiff == 0f) {
mPanListener?.onHasClose()
}
}
override fun onAnimationCancel(p0: Animator?) {
}
override fun onAnimationStart(p0: Animator?) {
}
})
mJumpAnimator!!.duration = 1200
}
mJumpAnimator!!.start()
}
复制代码
- 1.实现颗粒物无方向飘动
- 2.顺时针向圆心运动就是实现被设备吸入效果
这个实现过程更简单了每次改变更画的时间但要记住起点是上一次动画结束点,终点是结束点+360ide