一.重点属性讲解
1.KeyFrameSet
作用:指定运动序列过程中视图的位置和属性。默认情况下,运动会从初始状态逐渐进入结束状态。可以构建更复杂的运动。
KeyFrameSet 包含 <KeyPosition> 或 <KeyAttribute> 节点。这些节点中的每个节点都指定目标视图在运动特定点处的位置或属性。
2.KeyPosition
作用:指定视图在运动序列中特定时刻的位置。该属性用于调整默认的运动路径。包含于<KeyFrameSet>。
属性
<1> motion:motionTarget:被控制视图的Id。
<2> motion:framePosition:[1-99] 之间的整数。用于指定运动序列中视图何时到达此 <KeyPosition> 指定的点。例如,如果 framePosition 为 25,则视图在整个运动路径的四分之一处到达指定点。
<3> motion:percentX&motion:percentY:是相对于父视图指定的。X 为横轴,范围从 0(左端)到 1(右端)。Y 为纵轴,其中 0 为顶部,1 为底部。
可能的设置包括:
[1] parentRelative:percentX 和 percentY 是相对于父视图指定的。X 为横轴,范围从 0(左端)到 1(右端)。Y 为纵轴,其中 0 为顶部,1 为底部。
例如,如果您希望目标视图到达父视图右端中间的某个点,可以将 percentX 设置为 1,将 percentY 设置为 0.5。
[2] deltaRelative:percentX 和 percentY 是相对于视图在整个运动序列过程中移动的距离指定的。X 为横轴,Y 为纵轴;在这两种情况下,0 为视图在该轴上的起始位置,1 为最终位置。
例如,假设目标视图向上移动 100 dp,然后再向右移动 100 dp,但是您希望视图按以下方式移动:首先在运动的前四分之一部分向上移动 40 dp,然后向上呈弧形移动。为此,请将 framePosition 设置为 25,将 keyPositionType 设置为 deltaRelative,并将 percentY 设置为 -0.4。
[3] pathRelative:X 轴是目标视图在路径范围内移动的方向,其中 0 为起始位置,1 为最终位置。Y 轴垂直于 X 轴,正值位于路径左侧,负值位于右侧;设置一个非零的 percentY 可使视图向一个方向或另一个方向呈弧形运动。因此,视图的初始位置为 (0,0),最终位置为 (1,0)。
例如,假设您希望视图按如下方式移动:在运动序列前半部分的移动距离占总距离的 10%,然后加速移动以覆盖剩余 90% 的距离。为此,请将 framePosition 设置为 50,将 keyPositionType 设置为 pathRelative,并将 percentX 设置为 0.1。
3.KeyAttribute
作用:指定视图在运动序列中特定时刻的属性。可以使用 <KeyAttribute> 设置视图的任何标准属性。
例如,假设视图的不透明度 (android:alpha) 在初始 <ConstraintSet> 中设为 0,在最终 <ConstraintSet> 中设为 1。默认情况下,这会导致视图在整个运动序列上以线性方式淡入。如果您希望视图直至运动序列 80% 处都保持不可见,然后快速淡入,请添加单个 <KeyAttribute> 节点,将 motion:framePosition 设为 80 并将 android:alpha 设为 0。
属性
<1> motion:motionTarget:被控制视图的Id。
<2> motion:framePosition:从 1 到 99 之间的整数,用于指定在运动序列中视图何时具有该 <KeyAttribute> 指定的属性。例如,如果 framePosition 为 25,则视图在运动的四分之一处具有指定属性。
具体哪些属性
二.KeyFrameSet基础使用
1.布局文件
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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/activity_main_constraintlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ConstraintLayoutActivity">
<androidx.constraintlayout.motion.widget.MotionLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="@xml/activity_constraint_layout_scene"
app:motionDebug="SHOW_PATH">
<ImageView
android:id="@+id/imageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@color/colorPrimaryDark" />
</androidx.constraintlayout.motion.widget.MotionLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
2.描述文件
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- 开始ConstraintSet集合 -->
<ConstraintSet android:id="@+id/start">
<!-- 开始ImageView位置 左下角 -->
<Constraint
android:id="@id/imageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginLeft="20dp"
android:layout_marginBottom="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" />
</ConstraintSet>
<!-- 结束ConstraintSet集合 -->
<ConstraintSet android:id="@+id/end">
<!-- 结束ImageView位置 右下角 -->
<Constraint
android:id="@id/imageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</ConstraintSet>
<!-- Transition 轨迹 -->
<Transition
app:constraintSetEnd="@id/end"
app:constraintSetStart="@id/start">
<!-- KeyFrameSet集合 -->
<KeyFrameSet>
<!-- KeyPosition确定运动过程中的位置 具体值讲解如上 -->
<KeyPosition
app:framePosition="50"
app:keyPositionType="parentRelative"
app:motionTarget="@id/imageView"
app:percentY="0.5" />
<!-- KeyAttribute确定运动过程中的属性 具体值讲解如上 -->
<KeyAttribute
android:rotation="-360"
android:scaleX="2.0"
android:scaleY="2.0"
app:framePosition="50"
app:motionTarget="@id/imageView" />
<!-- KeyAttribute确定运动过程中的属性 具体值讲解如上 -->
<KeyAttribute
android:rotation="-720"
android:scaleX="1.0"
android:scaleY="1.0"
app:framePosition="100"
app:motionTarget="@id/imageView" />
</KeyFrameSet>
<OnSwipe
app:dragDirection="dragRight"
app:touchAnchorId="@id/imageView"
app:touchAnchorSide="bottom" />
</Transition>
</MotionScene>
3.结果
<KeyPosition
app:framePosition="50"
app:keyPositionType="parentRelative"
app:motionTarget="@id/imageView"
app:percentY="0.5" />
app:framePosition="50" 移动的前半部分50%
app:keyPositionType="parentRelative" app:percentX&app:percentY 相对于父视图指定
app:motionTarget="@id/imageView" 受控制的View的Id
app:percentY="0.5" Y 为纵轴,Y的中间位置是移动的中间位置。
<2> KeyAttribute 移动的前半部分50%
<KeyAttribute
android:rotation="-360"
android:scaleX="2.0"
android:scaleY="2.0"
app:framePosition="50"
app:motionTarget="@id/imageView" />
app:motionTarget="@id/imageView" 受控制的View的Id
app:framePosition="50" 运动的二分之一处具有指定属性
android:rotation="-360" 普通View的属性 逆时针旋转一周
android:scaleX="2.0" 普通View的属性 X轴变大一倍
android:scaleY="2.0" 普通View的属性 Y轴变大一倍
<3> KeyAttribute 移动的后半部分50%
<KeyAttribute
android:rotation="-720"
android:scaleX="1.0"
android:scaleY="1.0"
app:framePosition="100"
app:motionTarget="@id/imageView" />
app:motionTarget="@id/imageView" 受控制的View的Id
app:framePosition="100" 运动的最后处具有指定属性
android:rotation="-720" 普通View的属性 逆时针旋转两周
android:scaleX="1.0" 普通View的属性 X轴成原来的大小
android:scaleY="1.0" 普通View的属性 Y轴成原来的大小