我使用 MotionLayout 为选定的礼品卡设置动画。卡片本身是一个 CustomView,里面有一个 TickerView 和两个 TextView。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/openGiftContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_new_loyalty_rewarding_corners_card"
android:gravity="center_horizontal"
android:layout_gravity="center_horizontal"
android:paddingVertical="@dimen/grid_3"
android:orientation="vertical">
<ru.secret.secret.customviews.v3.ticker.TickerView
android:id="@+id/ivIconTicker"
android:layout_width="@dimen/grid_9"
android:layout_height="@dimen/grid_9"
tools:srcCompat="@drawable/circle_blue" />
<TextView
android:id="@+id/tvTitle"
style="@style/H0.TxtIconAlwaysBlack"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/grid_3_5"
android:gravity="center"
android:maxLines="2"
android:ellipsize="end"
android:paddingHorizontal="@dimen/grid_2"
tools:text="word1 word2 word3 word4 word5 word6 word7 word8 word9 word10" />
<TextView
android:id="@+id/tvDescription"
style="@style/Body1.Regular.TxtIconNeutrals2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/grid_2_5"
android:gravity="center"
android:maxLines="2"
android:ellipsize="end"
android:paddingHorizontal="@dimen/grid_3_5"
tools:text="word1 word2 word3 word4 word5 word6 word7 word8 word9 word10"
tools:visibility="visible" />
</LinearLayout>
不同长度的文本可能来自 TextView 的后端,但我们希望它不超过两行。 MotionScene 和片段布局中的 CustomView 宽度设置为 `match_parrent
问题是宽度到处都设置为match_parent,但我不确定视图旋转(rotationY)期间是否是这种情况。在动画期间,两个 TextView 第二行的单词都可以转到第一行。除了修复 CustomView 内布局的宽度和高度之外,我不知道如何解决此问题。还有更好的办法吗?
运动场景
<?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"
motion:defaultDuration="10000">
<Transition
android:id="@+id/transitionOpenGiftToCongrats"
motion:constraintSetEnd="@+id/endGiftScaleToCenter"
motion:constraintSetStart="@id/startGiftScaleToCenter">
<KeyFrameSet>
...
<!--CongratsOpenGiftView-->
<KeyAttribute
android:alpha="0"
motion:framePosition="0"
motion:motionTarget="@+id/congratsOpenGiftView" />
<KeyAttribute
android:alpha="0"
motion:framePosition="49"
motion:motionTarget="@+id/congratsOpenGiftView" />
<KeyAttribute
android:alpha="1"
motion:framePosition="50"
motion:motionTarget="@+id/congratsOpenGiftView" />
<KeyAttribute
android:alpha="1"
motion:framePosition="100"
motion:motionTarget="@+id/congratsOpenGiftView" />
...
</KeyFrameSet>
</Transition>
<ConstraintSet android:id="@+id/startGiftScaleToCenter">
...
<Constraint
android:id="@+id/congratsOpenGiftView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:alpha="0"
android:rotationY="180"
android:layout_marginStart="@dimen/grid_2"
android:layout_marginEnd="@dimen/grid_2"
motion:layout_constraintVertical_bias="0.5" />
</ConstraintSet>
<ConstraintSet android:id="@+id/endGiftScaleToCenter">
...
<Constraint
android:id="@+id/congratsOpenGiftView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:alpha="1"
android:rotationY="360"
android:layout_marginStart="@dimen/grid_2"
android:layout_marginEnd="@dimen/grid_2"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintVertical_bias="0.5" />
</MotionScene>
片段布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/rootML"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:background="@drawable/bg_choice_rewarding_liner_gradient"
app:layoutDescription="@xml/open_gift_to_congrats_scene">
...
<ru.broker.feature.loyalty.impl.view.new_views.CongratsOpenGiftView
android:id="@+id/congratsOpenGiftView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/grid_2"
android:layout_marginEnd="@dimen/grid_2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.5"/>
</androidx.constraintlayout.motion.widget.MotionLayout>
通过在自定义视图中设置文本视图的固定宽度来解决宽度不一致问题。
<!-- CongratsOpenGiftView.xml -->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ru.secret.secret.customviews.v3.ticker.TickerView
android:id="@+id/ivIconTicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/tvTitle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
tools:srcCompat="@drawable/circle_blue" />
<TextView
android:id="@+id/tvTitle"
style="@style/H0.TxtIconAlwaysBlack"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/grid_3_5"
android:gravity="center"
android:maxLines="2"
android:ellipsize="end"
android:paddingHorizontal="@dimen/grid_2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/ivIconTicker"
app:layout_constraintWidth_default="wrap"
tools:text="word1 word2 word3 word4 word5 word6 word7 word8 word9 word10" />
<TextView
android:id="@+id/tvDescription"
style="@style/Body1.Regular.TxtIconNeutrals2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/grid_2_5"
android:gravity="center"
android:maxLines="2"
android:ellipsize="end"
android:paddingHorizontal="@dimen/grid_3_5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvTitle"
app:layout_constraintWidth_default="wrap"
tools:text="word1 word2 word3 word4 word5 word6 word7 word8 word9 word10"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>