我正在尝试在滑动时为textview的边距,填充和Alpha设置动画。 一开始,textview没有填充,alpha为1。 最后,我希望alpha为0,填充为100dp,两侧为16dp dp余量,alpha为0.5 一切正常,除了填充没有改变。 MotionLayout是否支持填充? 我正在使用androidx.constraintlayout:constraintlayout:2.0.0-beta4。
添加更多文本,因为SO表示我的帖子看起来大部分是代码... 添加更多文本,因为SO表示我的帖子看起来主要是代码... 添加更多文本,因为SO表示我的帖子看起来主要是代码...
布局xml:
<androidx.constraintlayout.motion.widget.MotionLayout
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:id="@+id/layoutParent"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="@xml/test">
<TextView
android:id="@+id/fakenavigationBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="hello world">
</TextView>
</androidx.constraintlayout.motion.widget.MotionLayout>
动作场景:
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto">
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@id/fakenavigationBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:alpha="1"
android:padding="100dp"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintStart_toStartOf="parent">
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@id/fakenavigationBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:alpha="0.5"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintBottom_toBottomOf="parent">
</Constraint>
</ConstraintSet>
<Transition
motion:constraintSetStart="@+id/start"
motion:constraintSetEnd="@+id/end"
motion:duration="2000"
motion:motionInterpolator="linear">
<OnSwipe
motion:touchAnchorId="@+id/fakenavigationBar"
motion:touchAnchorSide="top"
motion:dragDirection="dragDown"/>
</Transition>
</MotionScene>
答案 0 :(得分:3)
我承认这不是一个非常有用的答案,但是我在填充方面也遇到了同样的问题。边距对于MotionLayout似乎可以正常工作,但似乎不支持填充。我要做的是使我的工作达到我想要的样子,就是将MotionLayout文件中的填充添加到所需的任何视图中。它考虑了该文件中的填充,但不考虑“运动场景约束集”中的填充,因此在我的情况下无法对填充进行动画处理。它将只保留在MotionLayout文件中设置的静态填充,这足以让我通过。
从this blog post看来,如果将Motion Scene过渡设置为在两个不同的布局之间(而不是ConstraintSet)之间,则可以在填充之间设置动画。
我已经向几个不同的资源问了一个问题,为什么MotionLayout不支持填充,如果我得到了有用的信息,它将更新我的答案,但据我所知,MotionLayout不支持动画填充值。 / p>
答案 1 :(得分:2)
这是MotionLayout的一个限制
Padding 不是受支持的属性 ConstraintSet,因此不支持它。 View setPaddingTop 甚至没有方法,因此不能将它们视为自定义属性。
这是 MotionLayout 中的一个空白,但存在填充问题。填充会随着视图尺寸的变化而更改请求布局的视图测量尺寸。 这很昂贵,因为解析动画的唯一方法是解析开始和结束约束集并重建插值。
最好重新设计布局以使用边距,因为这是布局的控件。
答案 2 :(得分:0)
这是可能的,但显然会付出很大的性能代价。
向您的 MotionLayout.TransitionListener
添加一个 MotionLayout
,用于计算给定进度值 (0f-1f) 的正确填充值,并将其设置为您在 onTransitionChange()
中的视图:
motionLayout.setTransitionListener(object : MotionLayout.TransitionListener {
override fun onTransitionStarted(motionLayout: MotionLayout, startId: Int, endId: Int) { }
override fun onTransitionChange(motionLayout: MotionLayout, startId: Int, endId: Int, progress: Float) {
val paddingInPx = calculatePaddingPx(progress)
myView.setPadding(paddingInPx, paddingInPx, paddingInPx, paddingInPx)
}
override fun onTransitionCompleted(motionLayout: MotionLayout, currentId: Int) { }
override fun onTransitionTrigger(motionLayout: MotionLayout, triggerId: Int, positive: Boolean, progress: Float) { }
})
在您的 MotionScene
中,添加:
<Transition motion:layoutDuringTransition="honorRequest"/>
另见:https://github.com/androidx/constraintlayout/issues/7#issuecomment-721447209
编辑 1:虽然我能够用这种技术改变填充,但我最终决定不使用它,因为性能影响在旧设备上非常明显。
Edit 2: 还有一个与滚动动画相关的问题,如果你做一个投掷,那么 TransitionListener
回调不能保证被调用,所以过渡将达到它的开始/结束状态没有更新填充。