Aug*_*rmo 1 android android-transitions android-constraintlayout constraintset
我有以下活动和布局:
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)
}
}
Run Code Online (Sandbox Code Playgroud)
<?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>
Run Code Online (Sandbox Code Playgroud)
当我尝试显示/隐藏底部蓝色时,会发生以下情况:
如你看到的,
有什么办法可以解决这些动画问题吗?我已经尝试了很多方法(使用ConstraintSet和Animation),但没有一个按预期工作。
您可以用于AutoTransition过渡。
TransitionManager.beginDelayedTransition(rootView, AutoTransition())
Run Code Online (Sandbox Code Playgroud)
结果会是这样的:
AutoTransition使用淡入淡出过渡来改变蓝色区域的可见性。如果您需要蓝色区域滑动,您应该提供自定义过渡。它应该是ChangeBounds红色区域和蓝色按钮的过渡以及Slide蓝色区域的过渡:
private val topRed: View by lazy { findViewById(R.id.topRed) }
private fun onSwitchButtonClicked(view: View) {
isBottomBlueViewShowing = !isBottomBlueViewShowing
val transitionSet = TransitionSet()
transitionSet.ordering = TransitionSet.ORDERING_TOGETHER
//blue btn
val blueBtnTransition = Slide(Gravity.BOTTOM)
blueBtnTransition.addTarget(bottomBlueView)
//red area + switch btn
val topRedTransition = ChangeBounds()
topRedTransition.addTarget(topRed)
topRedTransition.addTarget(switchButton)
transitionSet.addTransition(blueBtnTransition)
transitionSet.addTransition(topRedTransition)
val blueBtnVisibility = if (isBottomBlueViewShowing) {
View.VISIBLE
} else {
View.GONE
}
val constraintSet = ConstraintSet()
constraintSet.clone(rootView)
constraintSet.setVisibility(bottomBlueView.id, blueBtnVisibility)
TransitionManager.beginDelayedTransition(rootView, transitionSet)
constraintSet.applyTo(rootView)
}
Run Code Online (Sandbox Code Playgroud)
这是结果:
正如您所看到的,当它动画时,红色和蓝色区域之间仍然有白色区域。您可以通过在转换中添加延迟来解决这个问题:
blueBtnTransition.startDelay = if (isBottomBlueViewShowing) 0 else 100
topRedTransition.startDelay = if (isBottomBlueViewShowing) 100 else 0
Run Code Online (Sandbox Code Playgroud)
这是结果。恕我直言,有延迟的话看起来好多了:
| 归档时间: |
|
| 查看次数: |
1686 次 |
| 最近记录: |