更改 MotionLayout 中关键帧的 alpha

Changing the alpha in a keyframe in a MotionLayout

我有一个运动场景,它将一些视图转换到新位置并更改一些 alpha 值。到目前为止,MotionScene 基本上是线性的,这意味着它有一个开始状态和一个结束状态。

但是我希望有两个视图比其余视图更早处于 alpha 0。比如说在 10% 的过渡时,标题和副标题应该完全淡出。据我了解,这可以用 KeyFrameSet 来完成。我在 MotionScene 上做了一些工作,但我没有看到任何行为变化。任何帮助将不胜感激!

这是我的 MotionScene

<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">


    <Transition
        app:constraintSetEnd="@+id/end"
        app:constraintSetStart="@+id/start"
        app:duration="300">
        <OnSwipe
            app:dragDirection="dragDown"
            app:touchAnchorId="@+id/thumbnail" />


        <KeyFrameSet>
            <KeyAttribute
                android:alpha="1"
                app:motionProgress="0"
                app:motionTarget="@+id/title" />

            <KeyAttribute
                android:alpha="0"
                app:motionProgress="10"
                app:motionTarget="@+id/title" />

        </KeyFrameSet>

    </Transition>


    <ConstraintSet android:id="@+id/start">

        <Constraint
            android:id="@+id/background_card"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                app:attributeName="cornerRadiusDp"
                app:customFloatValue="0.0" />

        </Constraint>
    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">

        <Constraint
            android:id="@+id/background_card"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_marginRight="16dp"
            android:layout_marginBottom="16dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintRight_toRightOf="parent">
            <CustomAttribute
                app:attributeName="cornerRadiusDp"
                app:customFloatValue="16.0" />

        </Constraint>

        <Constraint
            android:id="@+id/thumbnail"
            android:layout_width="40dp"
            android:layout_height="40dp"
            app:layout_constraintBottom_toBottomOf="@+id/background_card"
            app:layout_constraintLeft_toLeftOf="@+id/background_card"
            app:layout_constraintRight_toRightOf="@+id/background_card"
            app:layout_constraintTop_toTopOf="@+id/background_card" />
        <Constraint
            android:id="@+id/background"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:alpha="0" />
        <Constraint
            android:id="@+id/toolbar"
            android:layout_width="0dp"
            android:layout_height="56dp"
            android:alpha="0"
            app:layout_constraintLeft_toLeftOf="@+id/background_card"
            app:layout_constraintRight_toRightOf="@+id/background_card"
            app:layout_constraintTop_toTopOf="@+id/background_card" />

        <Constraint
            android:id="@+id/controls_container"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:alpha="0"
            app:layout_constraintBottom_toBottomOf="@+id/background_card"
            app:layout_constraintLeft_toLeftOf="@+id/background_card"
            app:layout_constraintRight_toRightOf="@+id/background_card" />

        <Constraint
            android:id="@+id/title"
            app:layout_constraintBottom_toTopOf="@+id/subtitle"
            app:layout_constraintLeft_toLeftOf="@+id/background_card"
            app:layout_constraintRight_toRightOf="@+id/background_card" />

        <Constraint
            android:id="@+id/subtitle"
            app:layout_constraintBottom_toTopOf="@+id/controls_container"
            app:layout_constraintLeft_toLeftOf="@+id/background_card"
            app:layout_constraintRight_toRightOf="@+id/background_card" />


    </ConstraintSet>


</MotionScene>

我还没有玩过 KeyFrames,它们可能适用于此,但我对 motionStagger 稍作改动,它绝对适用于此。虽然数学有点棘手,但通过反复试验很容易找到您想要的间隔。

中,我询问了关于 motionStagger 的问题,最后试图解释数学,但这对我来说仍然有点棘手。如果您想深入了解,请查看 post。

我建议设置一个相当适中的 staggerValue 来开始并在您弄清楚哪个部分做什么时更多地使用它。如果您只有两组不同的视图要交错,那么将 motionStagger 设置为什么并不重要,只要知道具有较高值的​​视图将首先进行动画处理即可。您可能想要更多使用的值是 Transition 元素上的 motion:staggered

试试这段代码,看看它是否符合您的要求:

<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">


<Transition
    app:constraintSetEnd="@+id/end"
    app:constraintSetStart="@+id/start"
    app:duration="300"
    motion:staggered="0.6>  <--- mess around with this value
    <OnSwipe
        app:dragDirection="dragDown"
        app:touchAnchorId="@+id/thumbnail" />
</Transition>

<ConstraintSet android:id="@+id/start">
    <Constraint
        android:id="@+id/background_card"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent">
        <CustomAttribute
            app:attributeName="cornerRadiusDp"
            app:customFloatValue="0.0" />
        <Motion motion:motionStagger="1" />
    </Constraint>
    <Constraint
        android:id="@+id/title"
        app:layout_constraintBottom_toTopOf="@+id/subtitle"
        app:layout_constraintLeft_toLeftOf="@+id/background_card"
        app:layout_constraintRight_toRightOf="@+id/background_card" >
        <CustomAttribute
            motion:attributeName="alpha"
            motion:customFloatValue="1.0" />
        <Motion motion:motionStagger="2" />
    </Constraint>

    <Constraint
        android:id="@+id/subtitle"
        app:layout_constraintBottom_toTopOf="@+id/controls_container"
        app:layout_constraintLeft_toLeftOf="@+id/background_card"
        app:layout_constraintRight_toRightOf="@+id/background_card" >
        <CustomAttribute
            motion:attributeName="alpha"
            motion:customFloatValue="1.0" />
        <Motion motion:motionStagger="2" />
    </Constraint>
</ConstraintSet>

<ConstraintSet android:id="@+id/end">
    <Constraint
        android:id="@+id/background_card"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_marginRight="16dp"
        android:layout_marginBottom="16dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent">
        <CustomAttribute
            app:attributeName="cornerRadiusDp"
            app:customFloatValue="16.0" />
    </Constraint>

    <Constraint
        android:id="@+id/thumbnail"
        android:layout_width="40dp"
        android:layout_height="40dp"
        app:layout_constraintBottom_toBottomOf="@+id/background_card"
        app:layout_constraintLeft_toLeftOf="@+id/background_card"
        app:layout_constraintRight_toRightOf="@+id/background_card"
        app:layout_constraintTop_toTopOf="@+id/background_card" />

    <Constraint
        android:id="@+id/background"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:alpha="0" />

    <Constraint
        android:id="@+id/toolbar"
        android:layout_width="0dp"
        android:layout_height="56dp"
        android:alpha="0"
        app:layout_constraintLeft_toLeftOf="@+id/background_card"
        app:layout_constraintRight_toRightOf="@+id/background_card"
        app:layout_constraintTop_toTopOf="@+id/background_card" />

    <Constraint
        android:id="@+id/controls_container"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:alpha="0"
        app:layout_constraintBottom_toBottomOf="@+id/background_card"
        app:layout_constraintLeft_toLeftOf="@+id/background_card"
        app:layout_constraintRight_toRightOf="@+id/background_card" />

    <Constraint
        android:id="@+id/title"
        app:layout_constraintBottom_toTopOf="@+id/subtitle"
        app:layout_constraintLeft_toLeftOf="@+id/background_card"
        app:layout_constraintRight_toRightOf="@+id/background_card" >
        <CustomAttribute
            motion:attributeName="alpha"
            motion:customFloatValue="0.0" />
        <Motion motion:motionStagger="2" />
    </Constraint>

    <Constraint
        android:id="@+id/subtitle"
        app:layout_constraintBottom_toTopOf="@+id/controls_container"
        app:layout_constraintLeft_toLeftOf="@+id/background_card"
        app:layout_constraintRight_toRightOf="@+id/background_card" >
        <CustomAttribute
            motion:attributeName="alpha"
            motion:customFloatValue="0.0" />
        <Motion motion:motionStagger="2" />
    </Constraint>
</ConstraintSet>

希望对你有用!我在代码中标记了上面的行,这行会弄乱 stagger

为了让 alpha = 0 更早,KeyFrameSet 应该是这样的:

   <KeyFrameSet>
       <KeyAttribute
           motion:framePosition="0"
           motion:motionTarget="@id/view">
           <CustomAttribute
               motion:attributeName="alpha"
               motion:customFloatValue="1" />
       </KeyAttribute>

       <KeyAttribute
           motion:framePosition="50"
           motion:motionTarget="@id/view">
           <CustomAttribute
               motion:attributeName="alpha"
               motion:customFloatValue="0" />
       </KeyAttribute>
   </KeyFrameSet>

在这种情况下,“视图”将在动画中心变得不可见(因为 50)