我是Android开发的新手,并且正在尝试使用MotionLayout(ConstraintLayout 2.0.0 beta 2)。
我有一个带有多个LinearLayouts的MotionLayout。在运行时,我只希望在开始时显示一个(“折叠”状态),并在过渡结束时全部显示它们(“展开”状态)。此外,起始的LinearLayout可能会发生变化,例如,首先显示LinearLayoutA,用户展开MotionLayout,选择LinearLayoutB,然后在折叠时显示LinearLayoutB。
layout.xml:
<?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"
xmlns:tools="http://schemas.android.com/tools"
app:layoutDescription="@xml/test_motionscene"
android:id="@+id/motionLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="@+id/LinearLayoutA"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@android:color/holo_red_dark"
android:orientation="horizontal"
android:padding="15dp">
<TextView
android:id="@+id/text1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="LinearLayout A"
android:textAlignment="center" />
</LinearLayout>
<LinearLayout
android:id="@+id/LinearLayoutB"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@android:color/holo_green_dark"
android:orientation="horizontal"
android:padding="15dp">
<TextView
android:id="@+id/text2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="LinearLayout B"
android:textAlignment="center" />
</LinearLayout>
<LinearLayout
android:id="@+id/LinearLayoutC"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@android:color/holo_purple"
android:orientation="horizontal"
android:padding="15dp">
<TextView
android:id="@+id/text3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="LinearLayout C"
android:textAlignment="center" />
</LinearLayout>
<LinearLayout
android:id="@+id/LinearLayoutD"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@android:color/darker_gray"
android:orientation="horizontal"
android:padding="15dp">
<TextView
android:id="@+id/text4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="LinearLayout D"
android:textAlignment="center" />
</LinearLayout>
<LinearLayout
android:id="@+id/LinearLayoutE"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@android:color/holo_blue_dark"
android:orientation="horizontal"
android:padding="15dp">
<TextView
android:id="@+id/text5"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="LinearLayout E"
android:textAlignment="center" />
</LinearLayout>
<ImageView
android:id="@+id/test_icon"
style="@style/Widget.AppCompat.ActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
app:srcCompat="@android:drawable/arrow_down_float" />
<Button
android:id="@+id/show_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginBottom="8dp"
android:text="Show B"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/hide_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:text="Show D"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.motion.widget.MotionLayout>
test_motionscene.xml:
<?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"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Transition
motion:constraintSetStart="@+id/test_start"
motion:constraintSetEnd="@+id/test_end"
motion:duration="1000">
<OnSwipe
motion:touchAnchorId="@+id/test_icon"
motion:touchAnchorSide="bottom"
motion:dragDirection="dragDown" />
<OnClick
motion:targetId="@+id/test_icon"
motion:clickAction="toggle" />
</Transition>
<ConstraintSet android:id="@+id/test_start">
<Constraint
android:id="@+id/LinearLayoutA"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="@id/LinearLayoutB"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/LinearLayoutA" />
<Constraint
android:id="@id/LinearLayoutC"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/LinearLayoutB" />
<Constraint
android:id="@id/LinearLayoutD"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/LinearLayoutC" />
<Constraint
android:id="@id/LinearLayoutE"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/LinearLayoutD" />
<Constraint
android:id="@id/test_icon"
android:rotation="0"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/LinearLayoutE" />
</ConstraintSet>
<ConstraintSet android:id="@+id/test_end">
<Constraint
android:id="@+id/LinearLayoutA"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="@id/LinearLayoutB"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/LinearLayoutA" />
<Constraint
android:id="@id/LinearLayoutC"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/LinearLayoutB" />
<Constraint
android:id="@id/LinearLayoutD"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/LinearLayoutC" />
<Constraint
android:id="@id/LinearLayoutE"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/LinearLayoutD" />
<Constraint
android:id="@id/test_icon"
android:rotation="180"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/LinearLayoutE" />
</ConstraintSet>
</MotionScene>
我试图用onClick侦听器更改ConstraintSet,就像这样
// Clone the initial ConstraintSet
val constraint = ConstraintSet()
constraint.clone(motionLayout.getConstraintSet(R.id.test_start))
// On app launch, set LinearLayoutB to be displayed
motionLayout.setConstraintSet(
motionLayout.getConstraintSet(R.id.test_start).apply {
getConstraint(R.id.LinearLayoutB).apply {
layout.mHeight = ConstraintSet.WRAP_CONTENT
}
}
)
// OnClickListeners to change the LinearLayout displayed on collapse
LinearLayoutA.setOnClickListener {
Toast.makeText(this, "A clicked", Toast.LENGTH_SHORT).show()
val constaintClone = ConstraintSet()
constaintClone.clone(constraint)
motionLayout.setConstraintSet(
constaintClone.apply {
getConstraint(R.id.LinearLayoutA).apply {
layout.mHeight = ConstraintSet.WRAP_CONTENT
}
}
)
}
// Repeat the above for each LinearLayout
这不起作用,并且不会产生任何错误。
也许有一种方法可以更改MotionScene,以便我可以设置高度= WRAP_CONTENT的布局?
// Clone the scene
// The scene has heigh = 0 for all LinearLayouts
val scene = motionLayout.MotionScene.clone()
// Add onClickListener for each LinearLayout
// Set the height of only 1 LinearLayout to WRAP_CONTENT
LinearLayoutA.setOnClickListener {
motionLayout.setScene(
scene.apply {
test_start.LinearLayoutA.width = ConstraintSet.WRAP_CONTENT
}
)
}