MotionLayout 似乎在动画期间失去了一些约束
MotionLayout seems to lose some constraints during animation
我有一个问题:
我有一个 TextView,其内容通过 LiveData 不断变化。当动画不执行时这看起来没问题,但当 MotionLayout 开始执行时,我的文本被挡住了一点点。
而且我的TextView和Button的constraints都被packed了
activity:
class ErrorActivity : AppCompatActivity() {
private val mViewModel by viewModels<ErrorViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
DataBindingUtil.setContentView<ActivityErrorBinding>(this, R.layout.activity_error).apply {
lifecycleOwner = this@ErrorActivity
viewModel = mViewModel
}
}
fun startStopAnim(v: View) {
mViewModel.anim()
}
}
activity布局:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:binding="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewModel"
type="com.test.test.ErrorViewModel" />
</data>
<androidx.constraintlayout.motion.widget.MotionLayout
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="@xml/scene"
binding:anim="@{viewModel.mAnim}">
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{@string/test(viewModel.mCountDown)}"
android:textSize="32sp"
app:layout_constraintEnd_toStartOf="@+id/btn"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/test" />
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/tv"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/anim"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="startStopAnim"
android:text="startOrStop"
android:textAllCaps="false"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.motion.widget.MotionLayout>
</layout>
视图模型:
class ErrorViewModel : ViewModel() {
private val _countDown: MutableLiveData<String> = MutableLiveData()
val mCountDown: LiveData<String> = _countDown
private val _anim: MutableLiveData<Boolean> = MutableLiveData()
val mAnim: LiveData<Boolean> = _anim
private var count = 0
private var state = false
init {
viewModelScope.launch(Dispatchers.IO) {
while (true) {
delay(1000)
_countDown.postValue(count++.toString())
}
}
}
fun anim() {
state = !state
_anim.value = state
}
}
@BindingAdapter("anim")
fun anim(layout: MotionLayout, play: Boolean?) {
play?.let {
if (it) {
layout.transitionToEnd()
} else {
layout.transitionToStart()
}
}
}
运动场景:
为简单起见,场景只有一个持续时间
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:app="http://schemas.android.com/apk/res-auto">
<Transition
app:constraintSetEnd="@+id/end"
app:constraintSetStart="@+id/start"
app:duration="2000" />
</MotionScene>
gif
正如您在 gif 中看到的,当没有点击时,数字一切正常,但是当我点击按钮时,一个 2 秒的动画开始,在此期间我的文本无法正确显示。
当然,这只是一个演示示例。在真实场景中,不仅文字显示不完整,连TextView和ImageView都错位了,动画一旦执行就无法恢复。
谁能帮帮我...
实际上在真实场景中,有问题的TextView(A)的父布局(B)会执行位移动画。这个动画只要执行一次,TextView A的约束关系肯定会出问题,无法恢复(目前找到onPause后onResume可以恢复)
动画期间的设计使 MotionLayout 不支持 requestLayout。
因为在大多数应用程序中不需要它并且会对性能产生重大影响。
要在转换中启用它,请添加
<Transition ... motion:layoutDuringTransition="honorRequest" \>
我有一个问题: 我有一个 TextView,其内容通过 LiveData 不断变化。当动画不执行时这看起来没问题,但当 MotionLayout 开始执行时,我的文本被挡住了一点点。 而且我的TextView和Button的constraints都被packed了
activity:
class ErrorActivity : AppCompatActivity() {
private val mViewModel by viewModels<ErrorViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
DataBindingUtil.setContentView<ActivityErrorBinding>(this, R.layout.activity_error).apply {
lifecycleOwner = this@ErrorActivity
viewModel = mViewModel
}
}
fun startStopAnim(v: View) {
mViewModel.anim()
}
}
activity布局:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:binding="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewModel"
type="com.test.test.ErrorViewModel" />
</data>
<androidx.constraintlayout.motion.widget.MotionLayout
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="@xml/scene"
binding:anim="@{viewModel.mAnim}">
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{@string/test(viewModel.mCountDown)}"
android:textSize="32sp"
app:layout_constraintEnd_toStartOf="@+id/btn"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/test" />
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/tv"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/anim"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="startStopAnim"
android:text="startOrStop"
android:textAllCaps="false"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.motion.widget.MotionLayout>
</layout>
视图模型:
class ErrorViewModel : ViewModel() {
private val _countDown: MutableLiveData<String> = MutableLiveData()
val mCountDown: LiveData<String> = _countDown
private val _anim: MutableLiveData<Boolean> = MutableLiveData()
val mAnim: LiveData<Boolean> = _anim
private var count = 0
private var state = false
init {
viewModelScope.launch(Dispatchers.IO) {
while (true) {
delay(1000)
_countDown.postValue(count++.toString())
}
}
}
fun anim() {
state = !state
_anim.value = state
}
}
@BindingAdapter("anim")
fun anim(layout: MotionLayout, play: Boolean?) {
play?.let {
if (it) {
layout.transitionToEnd()
} else {
layout.transitionToStart()
}
}
}
运动场景:
为简单起见,场景只有一个持续时间
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:app="http://schemas.android.com/apk/res-auto">
<Transition
app:constraintSetEnd="@+id/end"
app:constraintSetStart="@+id/start"
app:duration="2000" />
</MotionScene>
gif 正如您在 gif 中看到的,当没有点击时,数字一切正常,但是当我点击按钮时,一个 2 秒的动画开始,在此期间我的文本无法正确显示。 当然,这只是一个演示示例。在真实场景中,不仅文字显示不完整,连TextView和ImageView都错位了,动画一旦执行就无法恢复。 谁能帮帮我...
实际上在真实场景中,有问题的TextView(A)的父布局(B)会执行位移动画。这个动画只要执行一次,TextView A的约束关系肯定会出问题,无法恢复(目前找到onPause后onResume可以恢复)
动画期间的设计使 MotionLayout 不支持 requestLayout。 因为在大多数应用程序中不需要它并且会对性能产生重大影响。
要在转换中启用它,请添加
<Transition ... motion:layoutDuringTransition="honorRequest" \>