花里胡哨切换背景色
说明:
很多情况会有切换背景或者主题的需求。
看一下这个效果:
(图片)
思路:
1.肯定需要绘制一个圆,圆的直径需要覆盖整个手机屏幕
2.圆在绘制过程中需要加载至布局之中,且位于背景色和按钮之间,否则无法看到渐变效果
3.绘制成功后,修改根布局背景色,移除绘制的圆,完成切换过程
实现:
方式1.绘制圆的过程中,可以使用postDelayed每延迟一段时间,刷新onDraw进行绘制,产生动画的感觉
private fun drawCicle(canvas: Canvas?, circleX: Float, circleY: Float) {
if (mRaduis > mMaxRaduis) {
fiexdBgColor(canvas)
this.isStartDraw = false
mListener.endCallBack()
return
}
canvas?.drawCircle(circleX, circleY, mRaduis, mPaint)
postDelayed(Runnable { mRaduis += 30; invalidate() }, 5)
}
方式2.直接使用值动画,将圆的半径设置为屏幕尺寸,在onAnimationUpdate回调函数中刷新onDraw进行绘制,使用动画的好处是可以很方便的控制时间,并且能使用插值器
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
this.mMaxRaduis = sqrt(w.toDouble().pow(2.0) + h.toDouble().pow(2.0)).toFloat()
valueAnimator = ValueAnimator.ofFloat(0F, mMaxRaduis)
valueAnimator.duration = 500
valueAnimator.addUpdateListener { animation ->
run {
mRaduis = animation.animatedValue as Float
postInvalidate()
}
}
valueAnimator.addListener(object : Animator.AnimatorListener {
override fun onAnimationRepeat(animation: Animator?) {
}
override fun onAnimationEnd(animation: Animator?) {
isStartDraw = false
mListener.endCallBack()
}
override fun onAnimationCancel(animation: Animator?) {
}
override fun onAnimationStart(animation: Animator?) {
}
})
valueAnimator.start()
}
细节部分
根布局移除圆View的时候,需要使用post,否则会可能出现异常:
“java.lang.NullPointerException: Attempt to read from field ‘int android.view.View.mViewFlags’ on a null object reference”
这是因为在快速点击按钮的时候,parentView一边在addView一边在removeView,使得管理混乱。
这里可以添加一把锁,正在添加的时候,禁止继续添加,保证切换动画中,始终保持只有一个View正在执行。
源码戳这里:WaveCircleView