Android 原生手机熄屏的时候可以看到屏幕饱和度会减低变灰,然后有一个缩放的动画再关闭屏幕。我一直很好奇这个饱和度变低的效果到底是如何实现的。今天决定来尝试用自己的方法实现一下类似的效果。
先上效果图
第一反应也是最容易想到的方法就是使用ValueAnimator在UpdateListener 里面遍历所有window.decorView
下的子View,依次改变其饱和度。但是不用想都能知道这个方法有很大的问题。如果界面的控件有很多的话,那光跑这个效果就足以榨干手机的性能了。编写Android 里面的动画效果其实有两个很重要的点。1.用尽量少的性能实现相同的效果 2.不要用物理的思维去实现(比如有些悬浮粘附效果其实只是两个View交替显示的障眼法)既然依次遍历不可行,那我是否可以只改变一个View来实现这个效果呢?
首先随便写一个带按钮的布局
关键是必须在最外层有一个match_parent
大小的ImageView
可以覆盖住整个布局
设置按钮的点击事件
btn.setOnClickListener {
val bitmap = Bitmap.createBitmap(
relative.width,
relative.height, Bitmap.Config.ARGB_8888
)
val canvas = Canvas(bitmap)
// window.decorView.draw(canvas)
relative.draw(canvas)
img_screen.setImageBitmap(bitmap)
val valueAni = ValueAnimator.ofInt(100, 10)
valueAni.duration = 1000
valueAni.addUpdateListener {
val i = it.animatedValue
cMatrix.setSaturation(((i) as Int).toFloat() / 100)
img_screen.colorFilter = ColorMatrixColorFilter(cMatrix)
}
valueAni.start()
}
就这么简单就实现这个整体饱和度渐变的效果了。
relative
是最外层的布局,通过relative.draw
方法将当前布局截图到bitmap,使用ValueAnimator 计算 1 - 0.1的饱和度,然后通过设置ImageView 的colorFilter 实现截图的遮罩效果。
虽然很简单的实现了饱和度变化的效果,但是这个方法局限性特别大,因为最外层的ImageView会遮挡到后面的View,因此需要配合的隐藏和显示这个ImageView,仅仅作为一个思路或者用于某些特殊场景(例如弹出PopurWindow时让背景变化)。