I have the following Activity and layout:
import android.os.Bundle
import android.view.Gravity
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.transition.Slide
import androidx.transition.TransitionManager
import com.tests.playground.R
class ConstraintLayoutTransitionActivity : AppCompatActivity() {
private val rootView: ConstraintLayout by lazy { findViewById(R.id.root) }
private val bottomBlueView: View by lazy { findViewById(R.id.bottomBlue) }
private val switchButton: View by lazy { findViewById(R.id.switchButton) }
private var isBottomBlueViewShowing = true
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_constraint_layout_transition)
switchButton.setOnClickListener(::onSwitchButtonClicked)
}
@Synchronized
private fun onSwitchButtonClicked(view: View) {
isBottomBlueViewShowing = !isBottomBlueViewShowing
val constraintSet = ConstraintSet()
constraintSet.clone(rootView)
val transition = Slide()
transition.duration = 1000L
if (isBottomBlueViewShowing) {
constraintSet.setVisibility(bottomBlueView.id, View.VISIBLE)
transition.slideEdge = Gravity.BOTTOM
} else {
constraintSet.setVisibility(bottomBlueView.id, View.GONE)
transition.slideEdge = Gravity.BOTTOM
}
TransitionManager.beginDelayedTransition(rootView, transition)
constraintSet.applyTo(rootView)
}
}
<?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"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="@+id/topRed"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#F00"
app:layout_constraintBottom_toTopOf="@+id/bottomBlue"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.button.MaterialButton
android:id="@+id/switchButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="Switch"
app:layout_constraintBottom_toBottomOf="@+id/topRed"
app:layout_constraintEnd_toEndOf="@+id/topRed"
app:layout_constraintStart_toStartOf="@+id/topRed"
app:layout_constraintTop_toTopOf="@+id/topRed" />
<View
android:id="@+id/bottomBlue"
android:layout_width="0dp"
android:layout_height="142dp"
android:background="#00F"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
When I try to show/hide the bottomBlue, here's what happens:
As you can see,
- when I hide the view the button goes straight down without animating (the bottomBlueView animation is ok`;
- when I show the view the button also goes straight up without animating. But what bugs me the most is that a white area is show before the animation starts and sticks there until the end.
Is there any way to solve theses animations problems?
I've already tried many ways (with ConstraintSet
and Animation
) but none of them work as expected.
You can use
AutoTransition
for transition.Result will be like this:
AutoTransition
uses Fade transition for visibility changes of blue area. If you need blue area to slide you should provide custom transition. It should beChangeBounds
transition for red area and blue button andSlide
transition for blue area:Here is result:
As you can see there is still white area between red and blue areas when it animates. You can solve it via adding delays to transitions:
Here is result. IMHO with delays it looks much better: