Introduction to the

MotionLayout, a new animation component released by Google, is a subclass of ConstraintLayout that allows Java/Kotlin code to animate between different states. Released with ConstraintLayout2.0, supported as low as API 14 for Android.

Note: MotionLayout cannot currently be used with the preferred declarative UI JetpackCompose

The introduction of

implementation 'androidx. Constraintlayout: constraintlayout: 2.0.4'
Copy the code

Structure & Basic usage

MotionLayout in THE XML layout needs to set the layoutDescription attribute, which creates an element tag in res/ XML with
as Root

Views defined under MotionLayout need to be animated in a direct subset and cannot be nested. If necessary, animation components need to be nested

Code example: 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>
Copy the code

Code example: res/ XML /activity_you_tube_layout_scene.xml To know the scene file structure

<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>
Copy the code

There should be one or more Transition tags in the MotionScene, which carry the beginning and end of the animation.

Transition:

  • constraintSetEndRecord the layout file structure at the end of the animation
  • constraintSetStartRecord the layout file structure at the beginning of the animation
  • durationToo much time
  • motionInterpolatorAnimation differentiator

OnSwipe: Specifies the action to be performed when the user swipes on the layout. The speed of the animation sequence and the animation of the target view are affected by the speed and direction of the slide, depending on the limits you set with optional parameters

  • touchAnchorIdThe view that moves after the slide
  • touchAnchorSideSlide the side of the target view to which it is fixed. MotionLayout will attempt to maintain a constant distance between this fixed point and the user’s finger. Acceptable values include “left”, “right”, “top”, and “bottom”.
  • dragDirectionThe direction of the user’s sliding action. If this property is set, theonSwipeWill only apply to sliding in a specific direction. Acceptable values include “dragLeft”, “dragRight”, “dragUp”, and “dragDown”.

  • maxAccelerationThe maximum acceleration of the target view.
  • dragScaleControls how far the view moves relative to the slide length. The default value is 1, indicating that the view should move the same distance as the slide.

OnClick: Description: Specifies what to do when the user clicks on a particular view.

  • targetIdA monitored view. When the user clicks on the view, the transformation takes place.
  • ClickActionWhat to do when you click on a view.

Keyframes can contain multiple Keypositions and multiple KeyAttribute Keypositions that specify the position of the view at a particular time in the motion sequence. This property is used to adjust the default motion path.

  • motionTargetId of the view you want to change.
  • framePositionAn integer between 1 and 99 that specifies when the view in the motion sequence arrives at this point<KeyPosition>Point specified.
  • percentX & percentYSpecify where the view should go.keyPositionTypeProperty specifies how to interpret the values.
  • keyPositionType
    • parentRelativePercentX and percentY are relative to the superview
    • deltaRelativePercentX and percentY are how far the view moves relative to the entire motion sequence

The KeyAttribute explanation: the control of key frames set view standard properties such as: the visibility, alpha, elevation, rotation, etc…

  • motionTargetId of the view you want to change.
  • framePositionAn integer between 1 and 99 that specifies when the view in the motion sequence arrives at this point<KeyPosition>Point specified.
  • View various standard properties, Android: Visibility,alpha, etc

ConstraintSet: Specifies the position and attributes of all views at a point in the animation sequence. In general, a
element can point to two

elements, one defining the beginning of an animation sequence and the other defining the end. Constraint specifies the position and attributes of one of the elements in the movement sequence. The element supports a set of standard ConstraintLayout attributes

  • idId of the bound View

CustomAttribute explanation: a label under Constraint that represents a CustomAttribute

  • attributeNameFor example, app:attributeName= “BackgroundColor” indicates that the BackgroundColor of the view needs to be changed
  • customColorValueFor example: app:customColorValue=”#FF0000″ Background color red

. There are many attribute details to view foreign documents, domestic documents

The sample not

File: 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>
Copy the code

The View that you want to change must have an Id and be a direct child of MotionLayout. In the animation file, bind it to the animation file 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>
Copy the code
  1. ConstraintMust be in its layout fileview IdConsistent, define twoConstraintSetTag, one isStart the animationLayout one isThe end of the animation,Set the layout ids toendandstartAnd then set its ID toTransitionOf the labelconstraintSetEndwithconstraintSetStart, and then transition time and differential, etc.
  2. inConstraintYou can see that each state of the view is set at the beginning and end respectively, one is the layout view changeslocationOne is the layout View changesThe background color
  3. OnSwipeSet up drag-and-drop view to adjust animation progress
  4. KeyFrameSetSet twoKey framesThe Settings, respectively, areKeyAttributeSettings changed at 30% animation progressIdforbuttonThe rotation Angle of view is -45 and the state property is twice the size of the original,KeyPositionChanged the path of the view 90% of the time to relativepathI’m going to change my Y axis to minus 0.3 or I’m going to move it up

How do we calculate and transition that we don’t really care about, the framework does that for us, right

The final result



After the completion of this case on the basic animation components and the definition of the way probably know, then directly do a beautiful animation is not impossible!

Sample Demo2

File: 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">. repeat</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>
Copy the code

Animation file: 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>
Copy the code
  1. And the property that’s in there, as I said above, pretty well understood, is in KeyPosition that says APP :percentWidth and this property is the percentage of the width of the targetView that converts at X percent progress

  2. Basic view changes alpha, transitionY/X/Z, ConstraintLayout position changes, etc

  3. There are two Transition tags in there, so you might not be able to select the appropriate animation in your XML. You need MotionLayout code to control this.

  4. After the layout is complete, the animation starts with a layout like this:



5. The animationThe end of the layout

. Assume that the corresponding data has been populated

In the effect picture, you can finally see that clicking the bottom suspension bar will make a transition animation, and then click close to move the bottom suspension bar down to transparent hide. The transitionids are container_transition_elsp and container_transition_hide_show so that you can optionally animate them in your code.

Java code:

 @Override
    protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_you_tube_layout);
         motionLayout = findViewById(R.id.motionlayout);
         // Set the motionLayout animation to container_transition_hide_show
         motionLayout.setTransition(R.id.container_transition_hide_show);
         // Hide progress with the hover bar at the bottom set to 1-> Progress: 100% direct hide
         motionLayout.setProgress(1);
         // Omit some code.//containerQ specifies the floating bar ID
         containerQ.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Do the same for the TransitionId in the animation layout file
                motionLayout.setTransition(R.id.container_transition_elsp);
                // Check whether the start/end ID of the current animation is the corresponding start/end ID of transition
                if (motionLayout.getCurrentState() == R.id.youtube_end) {
                    // End -> Start animation operation
                    motionLayout.transitionToStart();
                } else { 
                    //// Start -> End animation operationmotionLayout.transitionToEnd(); }}});// The close button of the hover bar performs the hidden animation
        clearImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            / / in the same way
                motionLayout.setTransition(R.id.container_transition_hide_show);
                if (motionLayout.getCurrentState() == R.id.youtube_start) {
                    motionLayout.transitionToEnd();
                } else{ motionLayout.transitionToStart(); }}}); }Copy the code

SetTransition, transitionToEnd, transitionToStart, getCurrentState(), and so on are all common motionLayout methods that can be viewed and used in documents

The final result

The last

See here the content of this piece is complete

Thank you for your visit, what is wrong with the place welcome correction