- 本文已受權微信公衆號: 鴻洋 (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