Состояние Android MotionLayout не обновляется при программном изменении ограничения - PullRequest
2 голосов
/ 20 июня 2019

У меня очень простой MotionLayout, и я пытаюсь программно изменить видимость одного из ограничений, чтобы вид отразил это изменение.Однако изменение не отражается до тех пор, пока я не уйду из текущего состояния, а затем вернусь к нему.Как вы получаете представление для обновления себя на основе нового ограничения немедленно?Я пробовал updateState(), rebuildScene() и invalidate(), но ни один из них, похоже, ничего не делал.

Вот представление:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout
        android:id="@+id/motion_layout"
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:showIn="@layout/activity_main"
        app:layoutDescription="@xml/motion_scene"
        tools:context=".MainActivity">

    <TextView
            android:id="@+id/left_to_right_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Left to right"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

    <TextView
            android:id="@+id/top_to_bottom_text"
            android:text="Top to bottom"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

</androidx.constraintlayout.motion.widget.MotionLayout>

Вот MotionScene:

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


    <Transition
            app:constraintSetStart="@id/base"
            app:constraintSetEnd="@id/bottom">
        <OnClick
                app:targetId="@id/top_to_bottom_text">

        </OnClick>

    </Transition>

    <Transition
            app:constraintSetStart="@id/base"
            app:constraintSetEnd="@id/right">
        <OnSwipe
                app:dragDirection="dragRight"
                app:touchAnchorId="@id/left_to_right_text"
                app:touchAnchorSide="right">

        </OnSwipe>

    </Transition>


    <ConstraintSet android:id="@+id/base">

        <Constraint
                android:id="@id/left_to_right_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toTopOf="parent"/>

        <Constraint
                android:id="@id/top_to_bottom_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toTopOf="parent"/>
    </ConstraintSet>

    <ConstraintSet android:id="@+id/bottom">

        <Constraint
                android:id="@id/left_to_right_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toTopOf="parent"/>

        <Constraint
                android:id="@id/top_to_bottom_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"
        />
    </ConstraintSet>

    <ConstraintSet android:id="@+id/right">

        <Constraint
                android:id="@id/left_to_right_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent"/>

        <Constraint
                android:id="@id/top_to_bottom_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toTopOf="parent"/>
    </ConstraintSet>
</MotionScene>

А вот код, где я пытаюсь обновить видимость одного изтекстовые просмотры через 2 секунды:

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(toolbar)

        Completable.timer(2, TimeUnit.SECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                motion_layout.getConstraintSet(R.id.base)?.let {
                    it.setVisibility(R.id.left_to_right_text, View.INVISIBLE)
                }
                motion_layout.updateState()
                // These don't work either
//                motion_layout.rebuildScene()
//                motion_layout.invalidate()
            }
    }

Вы можете увидеть в GIF ниже, я жду 2 секунды, и ничего не происходит.Только когда я перехожу в новое состояние и затем возвращаюсь к исходному состоянию, видимость обновляется.

Ответы [ 2 ]

2 голосов
/ 04 июля 2019

Я нашел решение!

Решение, предоставленное Phan Van Linh, не работает для меня (я использую версию ограничения 2.0.0-бета1)

Просто вызовите .requestLayout () для представления, которое вы только что изменили видимость (или другие свойства представления). Итак, в вашем примере:

motion_layout.getConstraintSet(R.id.base)?.let {
                it.setVisibility(R.id.left_to_right_text, View.INVISIBLE)
                yourView.requestLayout() // <-- this line
            }

Из-за документации для метода requestLayout он будет проходить через все представления`ы иерархия в настоящее время проходит макет.

0 голосов
/ 02 июля 2019

try: updateState (R.id.base, ConstraintSet)

...