I have a requirement where the view needs to be at the center of bottom and adjust the height based on its content. So created constraint layout
inside root constraint layout
to acheive this. But now I am facing a problem with animation. I am not able to apply constraintSet
.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#BEE">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/error_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="40dp"
android:background="#FFF"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<Button
android:id="@+id/error_try_again"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="6dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="12dp"
android:textStyle="bold"
android:minWidth="180dp"
android:text="Try again"
android:textAlignment="center"
android:textColor="#000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/error_subtitle" />
<TextView
android:id="@+id/error_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="12dp"
android:textStyle="bold"
android:text="We are unable to find the object"
android:textAlignment="center"
android:textColor="@color/black"
android:textSize="21sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/error_subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="6dp"
android:layout_marginEnd="12dp"
android:text="Try to keep the camera steady"
android:textAlignment="center"
android:textColor="@color/black"
android:textSize="12sp"
android:visibility="visible"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/error_title" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
constraintSet
how to restructure my layout (without nested groups)?constraintSet
is much straight forward to use.Tried calling this animation constraint set which will pass nested constraint as param error_layout
. But no changes on the result:
private void animateResult(ConstraintLayout constraint) {
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(this, R.layout.frameout_layout);
Transition transition = new ChangeBounds();
transition.setInterpolator(new AnticipateOvershootInterpolator(1.0f));
transition.setDuration(1200);
TransitionManager.beginDelayedTransition(constraint, transition);
constraintSet.applyTo(constraint);
}
Layout:
Remember, ConstraintSet Animation works as any other animation with two stages - Animation Start and Animation End. So, First set the view constraint as Animation start which means hidden under bottom of the layout.
So, Change the initial constraints as:
<!-- Here app:layout_constraintTop_toBottomOf will position the view under the layout/screen -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/error_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="40dp"
android:background="#fff"
android:visibility="visible"
app:layout_constraintTop_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
Then, create the constraints as
//rootLayout is the Id of the parent layout
val constraintSet = ConstraintSet()
constraintSet.clone(rootLayout)
constraintSet.clear(error_layout.id, ConstraintSet.TOP)
constraintSet.connect(error_layout.id, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM)
val transition: Transition = ChangeBounds()
transition.interpolator = AnticipateOvershootInterpolator(1.0f)
transition.duration = 1200
TransitionManager.beginDelayedTransition(rootLayout, transition)
constraintSet.applyTo(rootLayout)
Then, if you want to hide it again. Just replace the TOP and BOTTOM as
constraintSet.clear(error_layout.id, ConstraintSet.BOTTOM)
constraintSet.connect(error_layout.id, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM)
GIF took more time than coding :p.
EDIT - To listen to animation updates, especially Animation end as requested, what you can do is you can set a listener on transition
as
transition.addListener(object : Transition.TransitionListener {
override fun onTransitionStart(transition: Transition) {
}
override fun onTransitionEnd(transition: Transition) {
}
override fun onTransitionCancel(transition: Transition) {
}
override fun onTransitionPause(transition: Transition) {
}
override fun onTransitionResume(transition: Transition) {
}
})
Put it just before the beginDelayedTransition()
.