I have a very simple MotionLayout and I'm trying to change the visibility of one of the constraints programatically and have the view reflect that change. However the change isn't reflected until I transition away from the current state and then come back to it. How do you get the view to update itself based on the new constraint immediately? I've tried updateState(), rebuildScene() and invalidate() but none of them seem to do anything.
Here is the view:
<?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>
Here is the 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>
And here's the code where I'm attempting to update the visibility one of the text views after 2 seconds:
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()
}
}
You can see in the gif below, I wait 2 seconds and nothing happens. It's not until I transition to a new state and then come back to the original one that the visibility is updated.

from Android MotionLayout state not updating when changing constraint programatically
No comments:
Post a Comment