如何在MotionLayout中为LinearLayout内部子元素添加动画效果
问题根因
- MotionLayout仅支持对直接子控件的约束属性做动画控制,你布局里的3个Button是LinearLayout的子控件,不属于MotionLayout的直接子级,因此默认无法直接配置动画。
- 你当前的MotionScene还存在ID匹配错误:主布局中LinearLayout的ID是
linearLayout5,但ConstraintSet中引用的是不存在的linearLayout4,这个错误会导致连LinearLayout本身的动画都无法正常触发。
推荐解决方法:移除冗余LinearLayout
你这里用LinearLayout只是实现垂直排列的效果,完全可以用ConstraintLayout的约束实现相同效果,让所有Button成为MotionLayout的直接子控件,就可以自由配置每个Button的动画了。
修改后的主布局代码
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/motion_layout" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/activity_main_scene" tools:context=".MainActivity" tools:showpath="true" > <Button android:id="@+id/button16" android:layout_width="300dp" android:layout_height="wrap_content" android:layout_margin="20dp" android:text="onClick" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toTopOf="@id/button17" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintVertical_chainStyle="packed"/> <Button android:id="@+id/button17" android:layout_width="300dp" android:layout_height="wrap_content" android:layout_margin="20dp" android:text="onClick" app:layout_constraintTop_toBottomOf="@id/button16" app:layout_constraintBottom_toTopOf="@id/button18" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"/> <Button android:id="@+id/button18" android:layout_width="300dp" android:layout_height="wrap_content" android:layout_margin="20dp" android:text="onClick" app:layout_constraintTop_toBottomOf="@id/button17" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"/> </androidx.constraintlayout.motion.widget.MotionLayout>
对应的MotionScene示例(实现按钮依次左移入屏效果)
<?xml version="1.0" encoding="utf-8"?> <MotionScene xmlns:android="http://schemas.android.com/apk/res/android" xmlns:motion="http://schemas.android.com/apk/res-auto"> <Transition motion:constraintSetEnd="@+id/end" motion:constraintSetStart="@id/start" motion:duration="1000"> <KeyFrameSet> <!-- 给第二个按钮设置延迟效果 --> <KeyAttribute motion:framePosition="50" motion:motionTarget="@id/button17" android:alpha="0" /> <!-- 给第三个按钮设置延迟效果 --> <KeyAttribute motion:framePosition="70" motion:motionTarget="@id/button18" android:alpha="0" /> </KeyFrameSet> </Transition> <ConstraintSet android:id="@+id/start" > <!-- 起始状态:所有按钮在屏幕右侧外,透明度为0 --> <Constraint android:id="@+id/button16" android:alpha="0" motion:layout_constraintStart_toEndOf="parent" /> <Constraint android:id="@+id/button17" android:alpha="0" motion:layout_constraintStart_toEndOf="parent" /> <Constraint android:id="@+id/button18" android:alpha="0" motion:layout_constraintStart_toEndOf="parent" /> </ConstraintSet> <ConstraintSet android:id="@+id/end"> <!-- 结束状态:所有按钮回到居中位置,透明度为1 --> <Constraint android:id="@+id/button16" android:alpha="1" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" /> <Constraint android:id="@+id/button17" android:alpha="1" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" /> <Constraint android:id="@+id/button18" android:alpha="1" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" /> </ConstraintSet> </MotionScene>
必须保留LinearLayout的替代方案
如果业务逻辑需要必须保留LinearLayout结构,你只能通过CustomAttribute配置子控件的非位置类属性动画(比如透明度、缩放、旋转、背景色等),位置属性受LinearLayout的布局规则限制,无法通过MotionLayout直接控制,示例如下:
<ConstraintSet android:id="@+id/end"> <Constraint android:id="@+id/linearLayout5" > <!-- 控制内部第一个按钮的透明度 --> <CustomAttribute motion:attributeName="alpha" motion:customFloatValue="0.5" motion:targetId="@id/button16"/> <!-- 控制内部第二个按钮的缩放 --> <CustomAttribute motion:attributeName="scaleX" motion:customFloatValue="1.2" motion:targetId="@id/button17"/> </Constraint> </ConstraintSet>
内容的提问来源于stack exchange,提问作者Poorya Alishah Kamandi
相关产品推荐
相关产品推荐

