14

背景

我已经使用ViewAnimator / ViewSwitcher很长时间了。

我最常见的用例是从加载阶段切换到内容阶段,或者在向导的各个阶段之间切换,有时甚至会出现错误阶段。

问题

当我建议向“android-ktx”存储库(此处)添加一个不错的扩展功能时,有人告诉我:

ViewAnimator 不是我们积极推荐的用于动画视图的 API。它基于旧的动画系统,我们不想在这个库中推广它的使用。

我试过的

我看过 ViewAnimator 和 ViewSwitcher 的文章,包括文档。它并没有说它已被替换/弃用,或者建议使用其他东西。

问题

  1. 什么取代了 ViewAnimator?他是在谈论过渡吗?

  2. 与 ViewAnimator 相比有哪些优缺点?

  3. 给定一个带有一些视图的 ViewAnimator,如何将它转换为更新的解决方案,包括状态之间的切换?

4

3 回答 3

3

我假设Romain Guy 的意思ViewAnimator使用AnimationAPI,而考虑使用更新的 API Animator。请参阅文档中的“属性动画与视图动画 的区别” ,其中提到了每个 API 的优缺点以及使用场景:

视图动画系统提供了只为 View 对象设置动画的功能,因此如果您想为非 View 对象设置动画,您必须实现自己的代码来执行此操作。视图动画系统也受到限制,因为它只将视图对象的几个方面暴露给动画,例如视图的缩放和旋转,而不是背景颜色。

视图动画系统的另一个缺点是它只修改了视图的绘制位置,而不是实际的视图本身。例如,如果您为按钮设置动画以在屏幕上移动,则按钮可以正确绘制,但您可以单击按钮的实际位置不会改变,因此您必须实现自己的逻辑来处理此问题。

使用属性动画系统,这些约束被完全移除,您可以对任何对象(视图和非视图)的任何属性进行动画处理,并且对象本身实际上是被修改的。属性动画系统在执行动画的方式上也更加健壮。在较高级别上,您可以将动画师分配给您想要制作动画的属性,例如颜色、位置或大小,并且可以定义动画的各个方面,例如多个动画师的插值和同步。

然而,视图动画系统需要更少的时间来设置并且需要更少的代码来编写。如果视图动画完成了您需要做的所有事情,或者如果您现有的代码已经按照您想要的方式运行,则无需使用属性动画系统。如果出现用例,将两种动画系统用于不同的情况也可能有意义。

但是,没有直接的方法可以“转换ViewAnimator为使用更新的方法”,因为它在内部使用AnimationAPI。如文档中所述:“如果视图动画完成了您需要做的所有事情,或者如果您现有的代码已经按照您想要的方式运行,则无需使用属性动画系统”,这ViewAnimator就是不推荐使用的原因。

于 2018-02-26T12:04:20.673 回答
0

我想一种可能的替代方法是使用 ConstraintLayout 的转换,如此处所示。

要实现,它似乎必须使用 2 个相似的布局,每个视图具有相同的 id,然后您可以在各个阶段之间切换,如下所示:

class MainActivity : AppCompatActivity() {
    private var show = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.circuit)
        backgroundImage.setOnClickListener {
            if(show)
                hideComponents() // if the animation is shown, we hide back the views
            else
                showComponents() // if the animation is NOT shown, we animate the views
        }
    }

    private fun showComponents(){
        show = true
        val constraintSet = ConstraintSet()
        constraintSet.clone(this, R.layout.circuit_detail)
        val transition = ChangeBounds()
        transition.interpolator = AnticipateOvershootInterpolator(1.0f)
        transition.duration = 1200
        TransitionManager.beginDelayedTransition(constraint, transition)
        constraintSet.applyTo(constraint)
    }

    private fun hideComponents(){
        show = false
        val constraintSet = ConstraintSet()
        constraintSet.clone(this, R.layout.circuit)
        val transition = ChangeBounds()
        transition.interpolator = AnticipateOvershootInterpolator(1.0f)
        transition.duration = 1200
        TransitionManager.beginDelayedTransition(constraint, transition)
        constraintSet.applyTo(constraint)
    }
}
于 2018-03-05T10:11:50.290 回答
0

尝试使用AdapterViewAnimatorAdapterViewAnimator需要子视图的适配器,因此它可能比 使用起来有些困难ViewAnimator,但它需要ViewAnimator类中的方法,例如showNext(),setInAnimation(ObjectAnimator)setOutAnimation(ObjectAnimator). 是的,您必须手动将所有动画重写到 ObjectAnimator。

于 2018-02-26T12:51:53.237 回答