奥利奥后可见性变化行为不同

Visibility change behavior is different after Oreo

我最近发现,根据您的 android SDK,当更改视图的可见性时,它的行为会有所不同。

在Oreo之前,当设置从VISIBLEGONE时,视图首先从alpha方面从1淡化到0,然后视图使用的地方崩溃。

对于 Oreo 及更高版本(我想我还没有在 Android Q 上测试过),当设置从 VISIBLEGONE 时,视图在褪色时崩溃,使用其他视图,因为 alpha 尚未设置为零。

我在这个特殊情况下没有找到任何东西,只是我不得不通过自定义我的视图自己在某些 post 上支持动画。

我会在下面回答自己。

所以我创建了自定义视图,经过大量调试后,我发现我需要重写 setAlpha 方法:

class CustomViewAnimation(context: Context, attributeSet: AttributeSet) : ConstraintLayout(context, attributeSet) {

    private fun callToSuper(alpha: Float) {
        super.setAlpha(alpha)
    }

    override fun setAlpha(alpha: Float) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
            super.setAlpha(alpha)
        else {
            if (this.visibility == View.GONE)
                super.setAlpha(0f)
            else if (this.visibility == View.VISIBLE && alpha != 1f)
                super.setAlpha(0f)
            else if (this.visibility == View.VISIBLE && alpha == 1f)
                this.animate()
                    .alpha(1f)
                    .setListener(object : Animator.AnimatorListener {
                        override fun onAnimationRepeat(animation: Animator?) {}

                        override fun onAnimationEnd(animation: Animator?) {
                            callToSuper(1f)
                        }

                        override fun onAnimationCancel(animation: Animator?) {}

                        override fun onAnimationStart(animation: Animator?) {}
                    })
        }
    }
}

您还必须在要更改可见性的代码中执行动画的其他部分:

if (view.visibility == View.VISIBLE) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        view.animate()
            .alpha(0.0f)
            .setListener(object : Animator.AnimatorListener {
                override fun onAnimationRepeat(animation: Animator?) {}

                    override fun onAnimationEnd(animation: Animator?) {
                        view.alpha = 0.0f
                        view.visibility = View.GONE
                    }

                        override fun onAnimationCancel(animation: Animator?) {}

                        override fun onAnimationStart(animation: Animator?) {}
                })
        } else
            view.visibility = View.GONE
    } else
        view.visibility = View.VISIBLE

由于条件太多,这可能不是最好的方法,但同样,我还没有找到任何其他方法,而且效果很好。