如何在 MotionLayout 过渡期间平滑更改可绘制资源?

Shm*_*ser 4 android android-animation android-motionlayout

我想在转换过程中更改 fab 按钮中的图像,但我还没有找到如何使用 xml 进行更改,因为 CustomAttribute 标记仅支持可绘制颜色作为值。我的解决方案是将 TransitionAdapter 设置为 MotionLayout 并在 onTransitionChange 函数中更改 drawable。

motionLayout.setTransitionListener(object : TransitionAdapter() {
            var fromStart = true
            var wasChanged = false

            override fun onTransitionChange(
                motionLayout: MotionLayout?,
                startId: Int,
                endId: Int,
                progress: Float
            ) {
                if (!wasChanged) {
                    if (fromStart && progress >= 0.5f) {
                        fab.setImageResource(R.drawable.ic_done_black_24dp)
                        wasChanged = true
                    }
                    if (!fromStart && progress <= 0.5f) {
                        fab.setImageResource(R.drawable.ic_add_black_24dp)
                        wasChanged = true
                    }
                }
            }

            override fun onTransitionCompleted(motionLayout: MotionLayout?, currentId: Int) {
                wasChanged = false
                fromStart = !fromStart
            }

        })
Run Code Online (Sandbox Code Playgroud)

但在这种情况下,图像会立即改变。有什么方法可以使过渡像 MotionLayout 中的常规过渡一样平滑?

kja*_*on2 5

在 MotionLayout 中有一种很好的方法可以为两个图像之间的变化设置动画。但是,Fab 交互可能有点棘手。如这篇博文所示,您可以使用 ImageFilterView 并设置源和备用源,然后在它们之间进行淡入淡出。直接从上面链接的博客文章中获取代码,这是 ImageFilterView 在 MotionLayout 中的外观示例

<android.support.constraint.utils.ImageFilterView
        android:id="@+id/image"
        android:background="@color/colorAccent"
        android:src="@drawable/roard"
        app:altSrc="@drawable/hoford"
        android:layout_width="64dp"
        android:layout_height="64dp"/>
Run Code Online (Sandbox Code Playgroud)

android:src你想要的第一个图像在哪里app:altSrc,你想要淡入淡出的第二个图像在哪里。下面也是直接从博客文章中截取的,是您的motionScene 中的约束条件。

<ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@+id/image"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_marginStart="8dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="crossfade"
                motion:customFloatValue="0" />
        </Constraint>
    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@+id/image"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_marginEnd="8dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="crossfade"
                motion:customFloatValue="1" />
        </Constraint>
    </ConstraintSet>
Run Code Online (Sandbox Code Playgroud)

将交叉淡入淡出值设置为自定义属性的位置。不确定这将如何与 Fab 一起玩,但这是我知道如何在两个图像之间制作动画的最佳方式。