将进度手动设置为MotionLayout时,它将清除所有约束 [英] When manually set progress to MotionLayout it clears all constraints

查看:118
本文介绍了将进度手动设置为MotionLayout时,它将清除所有约束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的MotionLayout有两个小部件,一个在MotionLayout中描述,第二个在场景文件中.

I have MotionLayout with two widgets, one is described in MotionLayout, second - in scene 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>

场景文件:

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

另一方面,假设您有一个带有十二个小部件的布局,但是您要制作动画的只有一个-Motion MotionScene中的ConstraintSet只需要包含该小部件的约束.

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.

库版本:

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的回答我找到了解决方法:

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));
    }
}

推荐答案

这很奇怪,布局检查器显示 test_view_static size:宽度= 0和高度= 0.

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

我对您的代码进行了一些更新:在onCreate中,在 test_view_static 上添加一个点击侦听器以执行进度,并且效果很好.

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

我尝试了另一件事:在我放入的onStart()方法中:

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

和MotionLayout的行为符合预期.就像您必须等待MotionLayout初始化之后才能更新进度一样.

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>

这篇关于将进度手动设置为MotionLayout时,它将清除所有约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆