如何在 MotionLayout 中为 wrap_content TextView 设置动画?
How to animate a wrap_content TextView in MotionLayout?
首先,我创建了一个minimal demo来演示这个问题。
我想做什么
我的屏幕顶部有 2 个 TextView
。第二个在第一个的右边,尺寸较小。两者都显示 API 返回的一些内容(所以我不知道它需要多长时间 - 即它们必须是 wrap_content
。)
现在我想实现一个带有过渡效果的粘性header:当用户向上滚动时,第一个TextView
会缩小到与第二个几乎相同的大小,并保持自己在屏幕顶部。要实现这一点,MotionLayout
似乎是一个完美的选择。
我的做法
由于我不知道内容的长度,所以为了动画第一个TextView
的大小,我只能选择下面的一个:
- 动画文本大小
- 动画比例
方法 1 可以通过 this 解决方案来完成。但是动画一点都不流畅所以不能用
所以我尝试了方法 2。layoutDescription
文件从
传输第一个 TextView
<Constraint
android:id="@+id/tvFirst"
android:layout_width="wrap_content"
android:layout_height="32dp"
app:layout_constraintTop_toBottomOf="@id/vTop"
app:layout_constraintStart_toStartOf="parent"/>
至
<Constraint
android:id="@+id/tvFirst"
android:layout_width="wrap_content"
android:layout_height="24dp"
app:layout_constraintTop_toBottomOf="@id/vTop"
app:layout_constraintStart_toStartOf="parent"
android:transformPivotX="0dp"
android:transformPivotY="0dp"
android:scaleX="0.6"
android:scaleY="0.6"/>
动画效果很好,但是
问题
TextView
的宽度不变。只是它的内容按比例缩小了。这里的问题是,我想让第二个TextView
贴在内容的末尾,但是现在它们之间有很大的差距
我尝试了什么
我尝试结合两种方法。即我创建了一个透明 TextView
作为第一个 TextView
的虚拟对象,它使用方法 1 (TextSize) 进行动画处理,并让第二个 TextView
约束到虚拟对象。但是,宽度变化仅在完成过渡后发生,第二个 TextView
在过渡期间仍停留在同一位置。
我的问题
如何使第二个 TextView
紧贴第一个 TextView
内容的末尾顺利地制作动画?
这是一个没有好的解决方案的已知问题。
默认情况下 MotionLayout 块在动画期间中继。
这可以通过标志 Transition:
来改变
<Transition motion:layoutDuringTransition="honorRequest" \>
这意味着每次通过时都会解析布局(这很慢),但可能适合您的需要。
另一种方法是使用旨在进行平滑缩放的 MotionLabel。
这是为了减轻缩放量化而设计的
具有属性 scaleFromTextSize
<androidx.constraintlayout.utils.widget.MotionLabel
app:textPanX="0"
app:scaleFromTextSize="40sp"
android:textSize="90sp"/>
这从大小中抓取文本的“轮廓”并将它们缩放到所需的大小。
从长远来看,我们正在为这个问题寻找更好的解决方案。
首先,我创建了一个minimal demo来演示这个问题。
我想做什么
我的屏幕顶部有 2 个 TextView
。第二个在第一个的右边,尺寸较小。两者都显示 API 返回的一些内容(所以我不知道它需要多长时间 - 即它们必须是 wrap_content
。)
现在我想实现一个带有过渡效果的粘性header:当用户向上滚动时,第一个TextView
会缩小到与第二个几乎相同的大小,并保持自己在屏幕顶部。要实现这一点,MotionLayout
似乎是一个完美的选择。
我的做法
由于我不知道内容的长度,所以为了动画第一个TextView
的大小,我只能选择下面的一个:
- 动画文本大小
- 动画比例
方法 1 可以通过 this 解决方案来完成。但是动画一点都不流畅所以不能用
所以我尝试了方法 2。layoutDescription
文件从
TextView
<Constraint
android:id="@+id/tvFirst"
android:layout_width="wrap_content"
android:layout_height="32dp"
app:layout_constraintTop_toBottomOf="@id/vTop"
app:layout_constraintStart_toStartOf="parent"/>
至
<Constraint
android:id="@+id/tvFirst"
android:layout_width="wrap_content"
android:layout_height="24dp"
app:layout_constraintTop_toBottomOf="@id/vTop"
app:layout_constraintStart_toStartOf="parent"
android:transformPivotX="0dp"
android:transformPivotY="0dp"
android:scaleX="0.6"
android:scaleY="0.6"/>
动画效果很好,但是
问题
TextView
的宽度不变。只是它的内容按比例缩小了。这里的问题是,我想让第二个TextView
贴在内容的末尾,但是现在它们之间有很大的差距
我尝试了什么
我尝试结合两种方法。即我创建了一个透明 TextView
作为第一个 TextView
的虚拟对象,它使用方法 1 (TextSize) 进行动画处理,并让第二个 TextView
约束到虚拟对象。但是,宽度变化仅在完成过渡后发生,第二个 TextView
在过渡期间仍停留在同一位置。
我的问题
如何使第二个 TextView
紧贴第一个 TextView
内容的末尾顺利地制作动画?
这是一个没有好的解决方案的已知问题。 默认情况下 MotionLayout 块在动画期间中继。 这可以通过标志 Transition:
来改变 <Transition motion:layoutDuringTransition="honorRequest" \>
这意味着每次通过时都会解析布局(这很慢),但可能适合您的需要。 另一种方法是使用旨在进行平滑缩放的 MotionLabel。
这是为了减轻缩放量化而设计的 具有属性 scaleFromTextSize
<androidx.constraintlayout.utils.widget.MotionLabel
app:textPanX="0"
app:scaleFromTextSize="40sp"
android:textSize="90sp"/>
这从大小中抓取文本的“轮廓”并将它们缩放到所需的大小。
从长远来看,我们正在为这个问题寻找更好的解决方案。