Search code examples
androidandroid-animationandroid-linearlayoutandroid-motionlayout

Use Elements of Linear Layout in Motion Layout


I want to use linearlayout in motionlayout but I have problem. When I want give animation to elements of linearlayout , I can't give any animations to elemnts that they are in linearlayout and i can just give animation to linearlayout. This is main xml file:

 <?xml version="1.0" encoding="utf-8"?>
<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:id="@+id/motion_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/activity_main_scene"
    tools:context=".MainActivity"
    tools:showpath="true" >

    <LinearLayout
        android:id="@+id/linearLayout5"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <Button
            android:id="@+id/button16"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="20dp"
            android:text="onClick" />

        <Button
            android:id="@+id/button17"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="20dp"
            android:text="onClick" />

        <Button
            android:id="@+id/button18"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="20dp"
            android:text="onClick" />
    </LinearLayout>
</androidx.constraintlayout.motion.widget.MotionLayout>

and this is layoutDescription file :

<?xml version="1.0" encoding="utf-8"?>
<MotionScene 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:motion="http://schemas.android.com/apk/res-auto">

    <Transition
        motion:constraintSetEnd="@+id/end"
        motion:constraintSetStart="@id/start"
        motion:duration="1000">
       <KeyFrameSet>

       </KeyFrameSet>
    </Transition>

    <ConstraintSet android:id="@+id/start" >
        <Constraint
            motion:layout_constraintEnd_toEndOf="parent"
            android:id="@+id/linearLayout4" />
    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
    </ConstraintSet>
</MotionScene>

Solution

  • On ViewGroup (e.g. MotionLayout) cannot manipulate the Views of another ViewGroup. In your case the LinearLayout defines the position of its views. (That's its job)

    You have several solutions:

    1. Nested MotionLayouts
    2. Flow
    3. Build ConstraintSets that have the same behavior as LinearLayout

    Nested MotionLayouts

    You would need to have two MotionScene files. Have the progress of one affect the progress of another. (Add in ConstraintSet <ConstraintOverrid android:id:="child" motion:motionProgress="0 or 1" >

    Flow

    Flow allows you to flatten the hierarchy but achieve behaviors like linear layout There are many articles on this the most direct to your need is "ConstraintLayout Flow, Bye Bye to LinerLayout" Since MotionLayout implements all the features of ConstraintLayout so this will work.

    Note. To retain separation and reuse (If that was the goal you can put the views in a separate include.

    Emulate LinearLayout with constraints

    This is the lightest. Create a vertical chain and constrain the start and end to the parent. (Most introductions to ConstraintLayout describe this.