MotionLayout属性详解

上一章节讲述了MotionLayout最基础的使用。

MotionLayout基础详解

MotionLayout基础详解_motionlayout 官网_jianning-wu的博客-CSDN博客

本章节讲述MotionLayout的各种属性

一.MotionLayout的九大属性

1.MotionScene

标签:<MotionScene>

说明:运动场景文件的根元素。

详解:<MotionScene> 包含一个或多个 <Transition> 元素,每个元素用于定义运动序列的开始和结束状态,以及这两种状态之间的转换。必须包含<Transition>元素。可以包含<ConstraintSet>元素。

属性:defaultDuration 所有过渡的默认持续时间(以毫秒为单位)。默认持续时间用于未指定自己的持续时间的任何运动序列。例如,在设置了 defaultDuration="300" 的情况下,如果所有运动序列都没有明确指定自己的持续时间,则默认持续时间为 300 毫秒。

2.ConstraintSet

标签:<ConstraintSet>

说明:指定所有视图在运动序列中某一点处的位置和属性。

详解:通常,一个 <Transition> 元素可指向两个 <ConstraintSet> 元素,其中一个定义动画序列的开始,另一个定义结束。必须包含一个或多个 <Constraint> 元素。包含于<MotionScene>标签内

属性:

deriveConstraintsFrom(可选)另一个 ConstraintSet 的 ID。如果指定此属性,相应集内的所有约束条件都将应用于此 ConstraintSet,除非此集明确替换它们。

android:id 此约束条件集的唯一标识符。<Transition> 需要此 ID 来确定动画序列的起点和终点。

3.Constraint

标签:<Constraint>

说明:指定运动序列其中一个元素的位置和属性。

详解:包含于<ConstraintSet>标签内。

属性:<Constraint> 元素支持一组标准 ConstraintLayout 属性。

4.Transition

标签:<Transition>

说明:指定运动序列的开始和结束状态、任何所需的中间状态以及触发该序列的用户交互。

详解:可以包含的元素<onClick> <onSwipe> <KeyFrameSet>。包含于<MotionScene>标签内。

属性:
motion:constraintSetStart 运动序列的初始状态。可以是 <ConstraintSet> 的 ID,也可以是布局。如需指定 <ConstraintSet>,请将此属性设置为 "@+id/constraintSetId"。如需指定布局,请设置为 “@layout/layoutState”。

motion:constraintSetEnd 运动序列的最终状态。可以是 <ConstraintSet> 的 ID,也可以是布局。如需指定 <ConstraintSet>,请将此属性设置为 "@+id/constraintSetId"。如需指定布局,请设置为 “@layout/layoutState”。

motion:duration 运动序列的时长,以毫秒为单位。如果未指定,则使用 <MotionScene> 元素的 defaultDuration。

5.onClick

标签:<onClick>

说明:指定当用户点按特定视图时要执行的操作。

详解:单个 <Transition> 可以具有多个 <onClick> 节点,其中每个 <onClick> 可指定一个不同的目标视图和一个在点按此视图时要执行的其他操作。

属性:
motion:targetId 受监控的视图。当用户点按此视图时,将会发生转换。

motion:ClickAction 点按视图时要执行的操作。支持的值包括:

transitionToStart 为从当前布局到 <Transition> 元素的 motion::constraintSetStart 属性指定的布局添加动画效果。

transitionToEnd 为从当前布局到 <Transition> 元素的 motion:constraintSetEnd 属性指定的布局添加动画效果。

jumpToStart 从当前布局跳转到 <Transition> 元素的 motion::constraintSetStart 属性指定的布局。

jumpToEnd 从当前布局跳转到 <Transition> 元素的 motion:constraintSetEnd 属性指定的布局。

toggle 如果布局当前处于开始状态,请将动画效果切换为结束状态;否则,请将动画效果切换为开始状态。

6.onSwipe

标签:<onSwipe>

说明:指定当用户在布局上滑动时要执行的操作。

详解:动画序列的速度和目标视图的动画受滑动速度和方向的影响,具体取决于您使用可选参数设置的限制。单个 <Transition> 可以具有多个 <onSwipe> 节点,其中每个 <onSwipe> 可指定一个不同的滑动方向和一项在用户执行该滑动时要执行的其他操作。包含于<Transition>标签内。

属性:
motion:touchAnchorId 在滑动之后移动的视图。

motion:touchAnchorSide 滑动所固定到的目标视图的一侧。MotionLayout 将尝试在该固定点与用户手指之间保持恒定的距离。可接受的值包括 "left"、"right"、"top" 和 "bottom"。

motion:dragDirection 用户滑动动作的方向。如果设置了此属性,此 <onSwipe> 将仅适用于沿特定方向的滑动。可接受的值包括 "dragLeft"、"dragRight"、"dragUp" 和 "dragDown"。

motion:dragScale 控制视图相对于滑动长度的移动距离。默认值为 1,表明视图移动的距离应与滑动距离一致。如果 dragScale 小于 1,视图移动的距离会远远小于滑动距离(例如,dragScale 为 0.5 意味着如果滑动移动 4 厘米,目标视图会移动 2 厘米)。如果 dragScale 大于 1,视图移动的距离会大于滑动距离(例如,dragScale 为 1.5 意味着如果滑动移动 4 厘米,目标视图会移动 6 厘米)。

motion:maxVelocity 目标视图的最大速度。

motion:maxAcceleration 目标视图的最大加速度。

7.KeyFrameSet

标签:<KeyFrameSet>

说明:指定运动序列过程中视图的位置和属性。

详解:默认情况下,运动会从初始状态逐渐进入结束状态;通过使用 <KeyFrameSet>,您可以构建更复杂的运动。<KeyFrameSet> 包含 <KeyPosition> 或 <KeyAttribute> 节点。这些节点中的每个节点都指定目标视图在运动特定点处的位置或属性。MotionLayout 平滑地将视图从起点移至每个中间点,然后移至最终目标位置。

例如,假设运动序列的初始状态为在视图左下角有一个不透明球,而最终状态为该球到达右上角且完全透明。默认情况下,MotionLayout 会沿对角线移动此球,球体逐渐透明,直到到达目标位置为止。您可以使用 <KeyFrameSet> 更改此行为。例如,您可以将球设置为纵向移至左上角,同时保持完全不透明,然后水平移至右上角,同时淡出。您可以通过创建 <KeyFrameSet> 并在其中添加 <KeyPosition> 和 <KeyAttribute> 实现此目的。<KeyPosition> 表示球的中间位置,<KeyAttribute> 指定球在运动的中点保持不透明。

包含于<Transition>标签内。包含<KeyPosition> <KeyAttribute>

属性:无

8.KeyPosition

标签:<KeyPosition>

说明:指定视图在运动序列中特定时刻的位置。

详解:该属性用于调整默认的运动路径。

例如,如果某个对象从左上角开始到右下角结束,则默认的运动序列将按直线路径沿屏幕对角线向下移动该对象。通过添加一个或多个 <KeyPosition> 元素,可以使路径变形。

包含于<KeyFrameSet>

属性:
motion:motionTarget 其运动由此 <KeyPosition> 控制的视图。

motion:framePosition 1 到 99 之间的整数,用于指定运动序列中视图何时到达此 <KeyPosition> 指定的点。例如,如果 framePosition 为 25,则视图在整个运动路径的四分之一处到达指定点。

motion:percentX、motion:percentY 指定视图应到达的位置。keyPositionType 属性指定如何解释这些值。

motion:keyPositionType 指定如何解释 percentX 和 percentY 值。可能的设置包括:

parentRelative
percentX 和 percentY 是相对于父视图指定的。X 为横轴,范围从 0(左端)到 1(右端)。Y 为纵轴,其中 0 为顶部,1 为底部。

例如,如果您希望目标视图到达父视图右端中间的某个点,可以将 percentX 设置为 1,将 percentY 设置为 0.5。

deltaRelative
percentX 和 percentY 是相对于视图在整个运动序列过程中移动的距离指定的。X 为横轴,Y 为纵轴;在这两种情况下,0 为视图在该轴上的起始位置,1 为最终位置。

例如,假设目标视图向上移动 100 dp,然后再向右移动 100 dp,但是您希望视图按以下方式移动:首先在运动的前四分之一部分向上移动 40 dp,然后向上呈弧形移动。为此,请将 framePosition 设置为 25,将 keyPositionType 设置为 deltaRelative,并将 percentY 设置为 -0.4。

pathRelative
X 轴是目标视图在路径范围内移动的方向,其中 0 为起始位置,1 为最终位置。Y 轴垂直于 X 轴,正值位于路径左侧,负值位于右侧;设置一个非零的 percentY 可使视图向一个方向或另一个方向呈弧形运动。因此,视图的初始位置为 (0,0),最终位置为 (1,0)。

例如,假设您希望视图按如下方式移动:在运动序列前半部分的移动距离占总距离的 10%,然后加速移动以覆盖剩余 90% 的距离。为此,请将 framePosition 设置为 50,将 keyPositionType 设置为 pathRelative,并将 percentX 设置为 0.1。

9.KeyAttribute

标签:<KeyAttribute>

说明:指定视图在运动序列中特定时刻的属性。

详解:您可以使用 <KeyAttribute> 设置视图的任何标准属性。

例如,假设视图的不透明度 (android:alpha) 在初始 <ConstraintSet> 中设为 0,在最终 <ConstraintSet> 中设为 1。默认情况下,这会导致视图在整个运动序列上以线性方式淡入。如果您希望视图直至运动序列 80% 处都保持不可见,然后快速淡入,请添加单个 <KeyAttribute> 节点,将 motion:framePosition 设为 80 并将 android:alpha 设为 0。

包含于<KeyFrameSet>标签内。

属性:
motion:motionTarget 查看哪些属性受该 <KeyAttribute> 控制。

motion:framePosition 从 1 到 99 之间的整数,用于指定在运动序列中视图何时具有该 <KeyAttribute> 指定的属性。例如,如果 framePosition 为 25,则视图在运动的四分之一处具有指定属性。
您可以设置以下视图属性。如需详细了解这些属性,请参阅 View 参考文档。

android:visibility
android:alpha
android:elevation
android:rotation
android:rotationX
android:rotationY
transitionPathRotate
android:scaleX
android:scaleY
android:translationX
android:translationY
android:translationZ

附:官网

MotionLayout 参考文档  |  Android 开发者  |  Android Developers

二.MotionLayout属性综合使用

1.需求

实现,默认底部水平居中显示一个TextView。滑动这个TextView,显示出其他两个TextView。三个TextView一起上划。

2.代码

布局文件

<?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">


        <TextView
            android:id="@+id/leftTextView"
            android:layout_width="60dp"
            android:layout_height="40dp"
            android:background="@color/colorPrimaryDark"
            android:gravity="center"
            android:text="左边按钮"
            android:textColor="#FFFFFF"
            tools:ignore="HardcodedText" />

        <TextView
            android:id="@+id/midTextView"
            android:layout_width="60dp"
            android:layout_height="40dp"
            android:background="@color/colorAccent"
            android:gravity="center"
            android:text="中间按钮"
            android:textColor="#FFFFFF"
            tools:ignore="HardcodedText" />

        <TextView
            android:id="@+id/rightTexView"
            android:layout_width="60dp"
            android:layout_height="40dp"
            android:background="@color/colorPrimary"
            android:gravity="center"
            android:text="右边按钮"
            android:textColor="#FFFFFF"
            tools:ignore="HardcodedText" />

    </androidx.constraintlayout.motion.widget.MotionLayout>


</androidx.constraintlayout.widget.ConstraintLayout>

描述文件

<?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">

        <!-- 左边的TextView 底部水平居中 隐藏:android:alpha="0.0" -->
        <Constraint
            android:id="@+id/leftTextView"
            android:layout_width="60dp"
            android:layout_height="40dp"
            android:layout_marginBottom="20dp"
            android:alpha="0.0"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent" />

        <!-- 中间的TextView 底部水平居中  -->
        <Constraint
            android:id="@+id/midTextView"
            android:layout_width="60dp"
            android:layout_height="40dp"
            android:layout_marginBottom="20dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent" />

        <!-- 右边的TextView 底部水平居中 隐藏:android:alpha="0.0" -->
        <Constraint
            android:id="@+id/rightTexView"
            android:layout_width="60dp"
            android:layout_height="40dp"
            android:layout_marginBottom="20dp"
            android:alpha="0.0"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent" />

    </ConstraintSet>

    <!-- 结束ConstraintSet集合 -->
    <ConstraintSet android:id="@+id/end">

        <!-- 左边的TextView 顶部水平居中 屏幕左边  -->
        <Constraint
            android:id="@+id/leftTextView"
            android:layout_width="60dp"
            android:layout_height="40dp"
            android:layout_marginLeft="20dp"
            android:layout_marginTop="20dp"
            android:alpha="1.0"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <!-- 中间的TextView 顶部水平居中  -->
        <Constraint
            android:id="@+id/midTextView"
            android:layout_width="60dp"
            android:layout_height="40dp"
            android:layout_marginTop="20dp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <!-- 右边的TextView 顶部水平居中 屏幕右边  -->
        <Constraint
            android:id="@+id/rightTexView"
            android:layout_width="60dp"
            android:layout_height="40dp"
            android:layout_marginTop="20dp"
            android:layout_marginRight="20dp"
            android:alpha="1.0"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </ConstraintSet>

    <!-- 动画集合 描述 指定开始&结束的ConstraintSet -->
    <Transition
        app:constraintSetEnd="@id/end"
        app:constraintSetStart="@id/start">
        <!-- 指定集合 开始的方式  OnSwipe:滑动 onClick:点击 -->
        <OnSwipe app:touchAnchorId="@id/midTextView" />
    </Transition>

</MotionScene>

3.说明

<1> app:motionDebug="SHOW_PATH"属性 可以给MotionLayout布局加上调试 显示动画开始结束的路线。

<2> OnSwipe标签 说明动画开始的Action是滑动。

//在滑动之后移动的视图
app:touchAnchorId="@id/midTextView"


//滑动动作的方向
app:dragDirection="dragUp"
可接受的值包括 "dragLeft"、"dragRight"、"dragUp" 和 "dragDown"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值