Я новичок в разработке для Android и экспериментировал с MotionLayout (ConstraintLayout 2.0.0 beta 2).
У меня есть MotionLayout с несколькими LinearLayouts.Во время выполнения я хочу, чтобы только один отображался в начале (состояние «свернуто»), и отображать их все в конце перехода (состояние «развернуто»).Кроме того, начальный 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>
Я пытался изменить ConstraintSet с помощью прослушивателей onClick, например
// 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
}
)
}