如何使用MotionLayout为layout_constraintEnd属性添加中间状态动画?
解决方案
方法一:使用KeyConstraintSet(推荐)
这种方式贴合ConstraintSet的过渡逻辑,实现起来更直观:
- 在MotionScene中定义起始和目标两个ConstraintSet:
<ConstraintSet android:id="@+id/start"> <Constraint android:id="@id/my_view"> <!-- 起始状态:固定宽度,仅约束左边缘到父布局 --> <Layout android:layout_width="100dp" android:layout_height="wrap_content" app:layout_constraintStart_toStartOf="parent" app:layout_marginStart="16dp"/> </Constraint> </ConstraintSet> <ConstraintSet android:id="@+id/end"> <Constraint android:id="@id/my_view"> <!-- 目标状态:宽度设为0dp,同时约束左右边缘到父布局,实现拉伸 --> <Layout android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_marginStart="16dp" app:layout_marginEnd="16dp"/> </Constraint> </ConstraintSet>
- 在Transition中添加
KeyConstraintSet,指定70%动画进度时完成约束过渡:
<Transition app:constraintSetStart="@id/start" app:constraintSetEnd="@id/end" app:duration="1000"> <!-- 可根据需求调整总时长 --> <!-- 让约束过渡在70%进度时完成,后续保持目标状态 --> <KeyConstraintSet app:framePosition="70" app:constraintSet="@id/end"/> </Transition>
方法二:使用KeyAttribute控制宽度(替代方案)
如果不想额外定义ConstraintSet,可直接通过KeyAttribute动画视图宽度:
- 先在布局中给目标视图设置基础约束(左右均绑定父布局,初始宽度固定):
<View android:id="@+id/my_view" android:layout_width="100dp" android:layout_height="wrap_content" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_marginStart="16dp" app:layout_marginEnd="16dp"/>
- 在MotionScene的Transition中添加KeyAttribute,控制宽度从固定值过渡到0dp(即match_constraint):
<Transition app:constraintSetStart="@id/start" app:constraintSetEnd="@id/end" app:duration="1000"> <KeyAttribute app:motionTarget="@id/my_view" app:framePosition="0"> <CustomAttribute app:attributeName="layout_width" app:customDimension="100dp"/> </KeyAttribute> <KeyAttribute app:motionTarget="@id/my_view" app:framePosition="70"> <CustomAttribute app:attributeName="layout_width" app:customDimension="0dp"/> </KeyAttribute> </Transition>
原代码无效的原因
layout_constraintEnd_toEndOf属于ConstraintSet的约束关系属性,并非View自身的可动画属性,无法通过KeyAttribute的CustomAttribute直接设置。MotionLayout的CustomAttribute仅支持View自身属性(如width、alpha、translationX等),约束关系的变更需要通过ConstraintSet或KeyConstraintSet处理。
内容的提问来源于stack exchange,提问作者Oleh Liskovych
相关产品推荐
相关产品推荐

