简介
MotionLayout作为Google发布的新动画组件可谓是解决了部分Java/Kotlin代码编写动画代码的痛点,它是ConstraintLayout的子类允许其在不同状态之间设置布局动画,发布于版本ConstraintLayout2.0之后,最低支持到API 14的Android系统。
注意:目前
MotionLayout无法与推崇的声明式UI JetpackCompose一起使用
引入
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
结构&基本用法
MotionLayout在XML布局中需要去设置layoutDescription属性该属性对应的在res/xml中创建一个以<MotionScene></MotionScene>为Root的元素标签
MotionLayout下定义的view若要做动画需要在直接子集,不能嵌套若需求,则需要嵌套动画组件 代码示例:activity_you_tube_layout.xml
<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:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/motionlayout"
android:background="#666"
app:layoutDescription="@xml/activity_you_tube_layout_scene">
</androidx.constraintlayout.motion.widget.MotionLayout>
代码示例:res/xml/activity_you_tube_layout_scene.xml
要知道scene的文件结构
<Transition android:id="@+id/container_transition_elsp"
app:constraintSetEnd="@+id/youtube_end"
app:constraintSetStart="@+id/youtube_start"
app:duration="500"
app:motionInterpolator="easeInOut">
<OnSwipe/>
<OnClick/>
<KeyFrameSet>
<KeyPosition/>
<KeyAttribute/>
...
</KeyFrameSet>
</Transition>
<ConstraintSet android:id="@+id/youtube_hide_state">
<Constrain>
...
<CustomAttribute/>
</Constrain>
</ConstraintSet>
在MotionScene需要有一个或多个Transition标签,它承载着动画的开始与结束。
Transition:
constraintSetEnd记录动画结束的布局文件结构constraintSetStart记录动画开始时的布局文件结构duration过度时间motionInterpolator动画差值器 OnSwipe:
解释:指定当用户在布局上滑动时要执行的操作。动画序列的速度和目标视图的动画受滑动速度和方向的影响,具体取决于您使用可选参数设置的限制touchAnchorId在滑动之后移动的视图touchAnchorSide滑动所固定到的目标视图的一侧。MotionLayout 将尝试在该固定点与用户手指之间保持恒定的距离。可接受的值包括 "left"、"right"、"top" 和 "bottom"。dragDirection用户滑动动作的方向。如果设置了此属性,此onSwipe将仅适用于沿特定方向的滑动。可接受的值包括 "dragLeft"、"dragRight"、"dragUp" 和 "dragDown"。maxAcceleration目标视图的最大加速度。dragScale控制视图相对于滑动长度的移动距离。默认值为 1,表明视图移动的距离应与滑动距离一致。 OnClick:
解释:指定当用户点按特定视图时要执行的操作。targetId受监控的视图。当用户点按此视图时,将会发生转换。ClickAction点按视图时要执行的操作。 KeyFrameSet
解释:关键帧可以包含多个KeyPosition与多个KeyAttribute
KeyPosition
解释: 指定视图在运动序列中特定时刻的位置。该属性用于调整默认的运动路径。motionTarget需要作出改变的视图Id.framePosition1 到 99 之间的整数,用于指定运动序列中视图何时到达此<KeyPosition>指定的点。percentX & percentY指定视图应到达的位置。keyPositionType属性指定如何解释这些值。keyPositionTypeparentRelativepercentX 和 percentY 是相对于父视图deltaRelativepercentX 和 percentY 是相对于视图在整个运动序列过程中移动的距离 KeyAttribute
解释:设置关键帧的控制视图的标准属性例如: visibility,alpha,elevation,rotation,等...
motionTarget需要作出改变的视图Id.framePosition1 到 99 之间的整数,用于指定运动序列中视图何时到达此<KeyPosition>指定的点。View的各种标准属性,android:visibility,alpha等ConstraintSet
解释:指定所有视图在动画序列中某一点上的位置和属性。通常,一个<Transition>元素可指向两个<ConstraintSet>元素,其中一个定义动画序列的开始,另一个定义结束。 Constraint
解释:指定运动序列其中一个元素的位置和属性。元素支持一组标准ConstraintLayout属性id绑定的View Id CustomAttribute
解释:位于Constraint下的标签,表示自定义属性attributeName例如:app:attributeName=“BackgroundColor” 表示该view的背景颜色需要改变customColorValue例如:app:customColorValue="#FF0000"背景颜色红色 ...有很多属性详情可以查看国外文档 、国内文档
示例Demo1
文件: activity_scan4.xml
<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:layout_width="match_parent"
android:layout_height="match_parent"
app:showPaths="true"
tools:context=".Scan4Activity"
app:layoutDescription="@xml/activity_scan4_scene">
<View
android:id="@+id/button"
android:background="@color/colorAccent"
android:layout_width="64dp"
android:layout_height="64dp"
android:text="Button" />
</androidx.constraintlayout.motion.widget.MotionLayout>
定义需要变化的View务必要给出一个Id并且这个View是MotionLayout的直接子View在动画文件中需要将其绑定
动画文件:activity_scan4_scene.xml
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/button"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<CustomAttribute
app:attributeName="BackgroundColor"
app:customColorValue="#D81B60" />
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@id/button"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="parent">
<CustomAttribute
app:attributeName="BackgroundColor"
app:customColorValue="#9999FF" />
</Constraint>
</ConstraintSet>
<Transition
app:motionInterpolator="linear"
app:constraintSetEnd="@id/end"
app:constraintSetStart="@+id/start"
app:duration="1000">
<OnSwipe
app:dragDirection="dragRight"
app:touchAnchorId="@id/button"
app:touchAnchorSide="right" />
<KeyFrameSet>
<KeyAttribute
android:rotation="-45"
android:scaleX="2"
android:scaleY="2"
app:framePosition="30"
app:motionTarget="@id/button" />
<KeyPosition
app:framePosition="90"
app:keyPositionType="pathRelative"
app:motionTarget="@id/button"
app:percentY="-0.3" />
</KeyFrameSet>
</Transition>
</MotionScene>
Constraint中的id必须与其布局文件中的view Id一致,定义两个ConstraintSet标签,一个是起始动画布局一个是结束动画布局分别设置id为end和start,然后将其id设置到Transition标签的constraintSetEnd与constraintSetStart中,再接着过渡时间以及差值器等。- 在
Constraint中可以看到在起始与结束分别设置了view的各个状态,一个是布局View改变的位置,一个是布局View改变的背景颜色 OnSwipe设置了可拖拽进行动画进度调整的viewKeyFrameSet中设置了两个关键帧的设置,分别是KeyAttribute设置在动画进度为30%的时候改变了Id为button的view的旋转角度-45以及大小为原来倍的状态属性,KeyPosition在90%的时候改变了view的行经路线,以相对path进行改变 Y坐标轴变为-0.3也就是向上移动
具体如何计算以及过渡这个其实我们不需要关心,框架已经帮我们做了 最终效果
当完成这个案例之后基本对这个动画组件以及定义方式大概都知道了,那么直接做一个漂亮的动效也不是不可以!
示例Demo2
文件:activity_you_tube_layout.xml
<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:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/motionlayout"
android:background="#666"
app:layoutDescription="@xml/activity_you_tube_layout_scene"
tools:context=".YouTubeScanActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/container_q"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="80dp"
android:background="#fff"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<ImageView
android:id="@+id/image_small"
android:layout_width="120dp"
android:scaleType="centerCrop"
android:layout_height="0dp"
android:src="@drawable/sunset2"
app:layout_constraintBottom_toBottomOf="@id/container_q"
app:layout_constraintTop_toTopOf="@id/container_q" />
<ImageView
android:id="@+id/play_image"
android:clickable="true"
android:background="?selectableItemBackground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="@id/container_q"
app:layout_constraintTop_toTopOf="@id/container_q"
app:srcCompat="@drawable/ic_play_arrow_gray_32dp" />
<ImageView
android:background="?selectableItemBackground"
android:id="@+id/play_clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="@id/container_q"
app:layout_constraintTop_toTopOf="@id/container_q"
app:srcCompat="@drawable/ic_clear_gray_32dp" />
<TextView
android:id="@+id/text_row"
android:textSize="13sp"
android:lines="1"
android:ellipsize="end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="This is a text in an item"
/>
<androidx.core.widget.NestedScrollView
android:id="@+id/recyclerview"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#fff"
app:layout_constraintBottom_toBottomOf="@id/container_q"
app:layout_constraintEnd_toEndOf="@id/container_q"
app:layout_constraintStart_toStartOf="@id/container_q">
...重复
</androidx.core.widget.NestedScrollView>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/main_recyclerview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#fff"
app:layout_constraintBottom_toBottomOf="@id/bottom_navigation"
app:layout_constraintTop_toTopOf="parent"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="#fff"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/bottom_nav_menu" />
</androidx.constraintlayout.motion.widget.MotionLayout>
动画文件: res/xml/activity_you_tube_layout_scene.xml
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ConstraintSet android:id="@+id/youtube_start">
<Constraint
android:id="@+id/container_q"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="75dp"
android:elevation="5dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<CustomAttribute
app:attributeName="BackgroundColor"
app:customColorValue="#fff" />
</Constraint>
<Constraint
android:id="@+id/text_row"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:elevation="6dp"
app:layout_constraintBottom_toBottomOf="@id/container_q"
app:layout_constraintEnd_toEndOf="@id/play_image"
app:layout_constraintStart_toEndOf="@id/image_small"
app:layout_constraintTop_toTopOf="@id/container_q" />
<Constraint
android:id="@+id/image_small"
android:layout_width="120dp"
android:layout_height="0dp"
android:elevation="6dp"
android:scaleType="centerCrop"
android:src="@drawable/sunset2"
app:layout_constraintBottom_toBottomOf="@id/container_q"
app:layout_constraintStart_toStartOf="@id/container_q"
app:layout_constraintTop_toTopOf="@id/container_q" />
<Constraint
android:id="@+id/play_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="50dp"
android:alpha="1"
android:elevation="6dp"
app:layout_constraintBottom_toBottomOf="@id/container_q"
app:layout_constraintEnd_toEndOf="@id/play_clear"
app:layout_constraintTop_toTopOf="@id/container_q" />
<Constraint
android:id="@+id/play_clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:alpha="1"
android:elevation="6dp"
app:layout_constraintBottom_toBottomOf="@id/container_q"
app:layout_constraintEnd_toEndOf="@id/container_q"
app:layout_constraintTop_toTopOf="@id/container_q" />
<Constraint
android:id="@+id/recyclerview"
android:layout_width="0dp"
android:layout_height="0dp"
android:elevation="6dp"
app:layout_constraintBottom_toBottomOf="@id/container_q"
app:layout_constraintEnd_toEndOf="@id/container_q"
app:layout_constraintStart_toStartOf="@id/container_q">
<CustomAttribute
app:attributeName="BackgroundColor"
app:customColorValue="#fff" />
</Constraint>
<Constraint
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="#fff"
android:translationY="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/bottom_nav_menu" />
<Constraint
android:id="@+id/main_recyclerview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#fff"
app:layout_constraintBottom_toTopOf="@id/bottom_navigation"
app:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
<ConstraintSet android:id="@+id/youtube_end">
<Constraint
android:id="@+id/container_q"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:layout_marginBottom="0dp"
android:elevation="5dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="@+id/recyclerview"
android:layout_width="0dp"
android:layout_height="0dp"
android:elevation="6dp"
app:layout_constraintBottom_toBottomOf="@id/container_q"
app:layout_constraintEnd_toEndOf="@id/container_q"
app:layout_constraintStart_toStartOf="@id/container_q"
app:layout_constraintTop_toBottomOf="@id/image_small">
<CustomAttribute
app:attributeName="BackgroundColor"
app:customColorValue="#fff" />
</Constraint>
<Constraint
android:id="@+id/play_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="100dp"
android:alpha="0"
app:layout_constraintBottom_toBottomOf="@id/container_q"
app:layout_constraintEnd_toEndOf="@id/container_q"
app:layout_constraintTop_toTopOf="@id/container_q" />
<Constraint
android:id="@+id/image_small"
android:layout_width="0dp"
android:layout_height="300dp"
android:elevation="6dp"
android:scaleType="centerCrop"
android:src="@drawable/sunset2"
app:layout_constraintStart_toStartOf="@id/container_q"
app:layout_constraintTop_toBottomOf="@id/container_q"
app:layout_constraintTop_toTopOf="@id/container_q" />
<Constraint
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="#fff"
android:translationY="60dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/bottom_nav_menu" />
<Constraint
android:id="@+id/main_recyclerview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#fff"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
<Transition
android:id="@+id/container_transition_elsp"
app:constraintSetEnd="@+id/youtube_end"
app:constraintSetStart="@+id/youtube_start"
app:duration="500"
app:motionInterpolator="easeInOut">
<OnSwipe
app:dragDirection="dragUp"
app:touchAnchorId="@id/image_small"
app:touchAnchorSide="top" />
<KeyFrameSet>
<KeyPosition
app:curveFit="linear"
app:framePosition="5"
app:keyPositionType="parentRelative"
app:motionTarget="@id/image_small"
app:percentWidth="1"
app:percentX="0" />
<KeyPosition
app:curveFit="linear"
app:framePosition="30"
app:motionTarget="@id/container_q"
app:percentWidth="1" />
<KeyPosition
app:curveFit="linear"
app:framePosition="50"
app:motionTarget="@id/recyclerview"
app:percentWidth="1" />
<KeyAttribute
android:alpha="0"
app:curveFit="linear"
app:framePosition="0"
app:motionTarget="@id/recyclerview" />
<KeyAttribute
android:alpha="0"
app:curveFit="linear"
app:framePosition="40"
app:motionTarget="@id/recyclerview" />
<KeyAttribute
android:alpha="1"
app:curveFit="linear"
app:framePosition="100"
app:motionTarget="@id/recyclerview" />
<KeyAttribute
android:alpha="0"
app:curveFit="linear"
app:framePosition="30"
app:motionTarget="@id/play_image" />
<KeyAttribute
android:alpha="0"
app:curveFit="linear"
app:framePosition="30"
app:motionTarget="@id/play_clear" />
<KeyAttribute
android:alpha="0"
app:curveFit="linear"
app:framePosition="10"
app:motionTarget="@id/text_row" />
<KeyAttribute
android:translationY="-100dp"
app:curveFit="linear"
app:framePosition="30"
app:motionTarget="@id/container_q"
/>
<KeyAttribute
android:translationY="-100dp"
app:curveFit="linear"
app:framePosition="50"
app:motionTarget="@id/recyclerview"
/>
<KeyAttribute
android:translationY="-100dp"
app:curveFit="linear"
app:framePosition="50"
app:motionTarget="@id/play_image"
/>
<KeyAttribute
android:translationY="-100dp"
app:curveFit="linear"
app:framePosition="50"
app:motionTarget="@id/play_clear"
/>
<KeyAttribute
android:translationY="-100dp"
app:curveFit="linear"
app:framePosition="50"
app:motionTarget="@id/image_small" />
<KeyAttribute
android:translationY="-100dp"
app:curveFit="linear"
app:framePosition="50"
app:motionTarget="@id/text_row" />
</KeyFrameSet>
</Transition>
<Transition
android:id="@+id/container_transition_hide_show"
app:constraintSetEnd="@+id/youtube_hide_state"
app:constraintSetStart="@+id/youtube_start"
app:duration="300"
app:motionInterpolator="easeIn" />
<ConstraintSet android:id="@+id/youtube_hide_state">
<Constraint
android:id="@+id/container_q"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="-60dp"
android:alpha="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<CustomAttribute
app:attributeName="BackgroundColor"
app:customColorValue="#fff" />
</Constraint>
<Constraint
android:id="@+id/image_small"
android:layout_width="120dp"
android:layout_height="0dp"
android:alpha="0"
android:elevation="6dp"
android:scaleType="centerCrop"
android:src="@drawable/sunset2"
app:layout_constraintBottom_toBottomOf="@id/container_q"
app:layout_constraintStart_toStartOf="@id/container_q"
app:layout_constraintTop_toTopOf="@id/container_q" />
<Constraint
android:id="@+id/play_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="50dp"
android:alpha="0"
android:elevation="6dp"
app:layout_constraintBottom_toBottomOf="@id/container_q"
app:layout_constraintEnd_toEndOf="@id/play_clear"
app:layout_constraintTop_toTopOf="@id/container_q" />
<Constraint
android:id="@+id/text_row"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:alpha="0"
android:elevation="6dp"
app:layout_constraintBottom_toBottomOf="@id/container_q"
app:layout_constraintEnd_toEndOf="@id/play_image"
app:layout_constraintStart_toEndOf="@id/image_small"
app:layout_constraintTop_toTopOf="@id/container_q" />
<Constraint
android:id="@+id/play_clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:alpha="0"
android:elevation="6dp"
app:layout_constraintBottom_toBottomOf="@id/container_q"
app:layout_constraintEnd_toEndOf="@id/container_q"
app:layout_constraintTop_toTopOf="@id/container_q" />
<Constraint
android:id="@+id/recyclerview"
android:layout_width="0dp"
android:layout_height="0dp"
android:alpha="0"
android:elevation="6dp"
app:layout_constraintBottom_toBottomOf="@id/container_q"
app:layout_constraintEnd_toEndOf="@id/container_q"
app:layout_constraintStart_toStartOf="@id/container_q">
<CustomAttribute
app:attributeName="BackgroundColor"
app:customColorValue="#fff" />
</Constraint>
</ConstraintSet>
</MotionScene>
-
里面的属性上面以及说过了,很好理解的,
KeyPosition中有写app:percentWidth此属性是targetView的宽度比例在百分之X进度的时候进行转换 -
还是基本的view的改变
alpha、transitionY/X/Z以及ConstraintLayout约束中的位置的变化等 -
当然这里面有两个
Transition标签,这样在xml中可能无法正确选择相应的动画,接下来就需要MotionLayout代码进行控制了,此代码也很简单,下文中有写! -
布局完成之后是动画
起始布局这样一个布局:
5. 动画结束布局
...
假设已经完成相应的数据填充工作
在效果图中最终看到点击底部悬浮栏会进行转场动画,然后点击关闭底部悬浮栏下移透明隐藏,他们分别对应的Transitionid 是container_transition_elsp、container_transition_hide_show有了这两个Id在代码中即可使用有选择性的进行动画操作.
Java代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_you_tube_layout);
motionLayout = findViewById(R.id.motionlayout);
//设置motionlayout动画为container_transition_hide_show
motionLayout.setTransition(R.id.container_transition_hide_show);
//将其底部悬浮栏隐藏进度设置1->进度:100% 直接隐藏
motionLayout.setProgress(1);
//省略部分代码
...
//containerQ 为悬浮栏id
containerQ.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//同理设置动画布局文件中TransitionId
motionLayout.setTransition(R.id.container_transition_elsp);
//判断当前动画start/end id是否是transition对应的start/end Id
if (motionLayout.getCurrentState() == R.id.youtube_end) {
//结束->起始 动画操作
motionLayout.transitionToStart();
} else {
////起始->结束 动画操作
motionLayout.transitionToEnd();
}
}
});
//悬浮栏的关闭按钮 执行隐藏动画
clearImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//同理
motionLayout.setTransition(R.id.container_transition_hide_show);
if (motionLayout.getCurrentState() == R.id.youtube_start) {
motionLayout.transitionToEnd();
} else {
motionLayout.transitionToStart();
}
}
});
}
setTransition、transitionToEnd、transitionToStart、getCurrentState()等都是motionlayout公有方法可在文档中查阅并使用
最终效果
最后
看到这里本篇内容已经完成了