更改 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)
我有一个运动场景,它将一些视图转换到新位置并更改一些 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 稍作改动,它绝对适用于此。虽然数学有点棘手,但通过反复试验很容易找到您想要的间隔。
在
我建议设置一个相当适中的 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)