Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When manually set progress to MotionLayout it clears all constraints

I have MotionLayout with two widgets, one is described in MotionLayout, second - in scene file.

Layout file:

<android.support.constraint.motion.MotionLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/motion_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/scene_test">

    <View
        android:id="@+id/test_view_static"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:background="#ff0000"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:id="@+id/test_view_dynamic"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:background="#00ff11" />

</android.support.constraint.motion.MotionLayout>

Scene file:

<MotionScene xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <Transition
        app:constraintSetStart="@+id/start"
        app:constraintSetEnd="@+id/end"/>

    <ConstraintSet android:id="@id/start">

        <Constraint
            android:id="@+id/test_view_dynamic"
            android:layout_width="40dp"
            android:layout_height="40dp"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </ConstraintSet>

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

        <Constraint
            android:id="@id/test_view_dynamic"
            android:layout_width="40dp"
            android:layout_height="40dp"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintBottom_toBottomOf="parent" />

    </ConstraintSet>

</MotionScene>

Then in activity i set progress:

//onCreate, etc..
MotionLayout motionLayout = findViewById(R.id.motion_layout);
motionLayout.setProgress(0.5f);

Dynamic view is on right position, but static view loses all constraints, but it is not affected by scene, as described here, only the widget described in the scene file should be affected.

On the other hand, let’s say that you have a layout with a dozen widgets, but only one that you are animating — the ConstraintSet in MotionScene only need to contain the Constraint for that one widget.

Library version:

implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:2.0.0-alpha2'

Example project here: https://github.com/Anrimian/MotionLayoutIssueTest

Upd: Thanks for Kélian's answer I found solution:

public static void setProgress(MotionLayout motionLayout, float progress) {
    if (ViewCompat.isLaidOut(motionLayout)) {
        motionLayout.setProgress(progress);
    } else {
        motionLayout.post(() -> motionLayout.setProgress(progress));
    }
}
like image 226
Anrimian Avatar asked Aug 20 '18 10:08

Anrimian


1 Answers

This is weird, layout inspector show test_view_static size : width = 0 and height = 0.

I updated a bit your code : in onCreate add a click listener on test_view_static to perform the progress and it worked fine.

I tried another thing : in onStart() method i put :

Handler handler = new Handler();
handler.postDelayed(new Runnable() {
    public void run() {
        MotionLayout motionLayout = findViewById(R.id.motion_layout);
        motionLayout.setProgress(0.5f);
    }
}, 1000);

and the MotionLayout behave expectedely. It's like you have to wait the MotionLayout to be initialized before updating it's progress.

In fact you want to have another start layout that the one you discribed in the scene. You could do this without updating the progress with :

<ConstraintSet android:id="@id/start">
    <Constraint
        android:id="@+id/test_view_dynamic"
        android:layout_width="40dp"
        android:layout_height="40dp"
        motion:layout_constraintRight_toRightOf="parent"
        motion:layout_constraintTop_toTopOf="parent"
        motion:layout_constraintBottom_toBottomOf="parent" />
</ConstraintSet>
like image 118
Kélian Avatar answered Oct 13 '22 18:10

Kélian