当手动设置MotionLayout的进度时,它会清除所有约束条件。

7
我有一个MotionLayout,其中有两个小部件,一个在MotionLayout中描述,另一个在场景文件中描述。
布局文件:
<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>

场景文件:
<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>

然后在活动中设置进度:
//onCreate, etc..
MotionLayout motionLayout = findViewById(R.id.motion_layout);
motionLayout.setProgress(0.5f);

动态视图在正确的位置,但静态视图失去了所有约束条件,但它不受场景的影响,如此处所述,只有场景文件中描述的小部件应受到影响。
另一方面,假设您有一个包含十几个小部件的布局,但只有一个小部件正在进行动画 - MotionScene中的ConstraintSet只需要包含该小部件的约束条件。
库版本:
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:2.0.0-alpha2'

示例项目在这里:https://github.com/Anrimian/MotionLayoutIssueTest 更新:感谢Kélian的答案,我找到了解决方法:
public static void setProgress(MotionLayout motionLayout, float progress) {
    if (ViewCompat.isLaidOut(motionLayout)) {
        motionLayout.setProgress(progress);
    } else {
        motionLayout.post(() -> motionLayout.setProgress(progress));
    }
}
1个回答

6

这有些奇怪,布局检查器显示test_view_static的大小为:宽度为0,高度为0。

我稍微修改了你的代码:在onCreate中添加一个test_view_static的点击监听器来执行进度,结果很好。

我试过另一件事情:在onStart()方法中我放置了:

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

你希望MotionLayout表现正常。就像你必须等待MotionLayout初始化后才能更新进度一样。

实际上,你想要另一个起始布局而不是场景中描述的布局。你可以通过以下方式完成此操作,而无需更新进度:

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

1
你的回答提醒了我,每个布局都需要时间来初始化,所以解决方案更简单:motionLayout.post(() -> motionLayout.setProgress(progress));谢谢。 - Anrimian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接