Android MotionLayout 中多个过渡的问题



我在Android中玩MotionLayout。我使用的是 alpha 2 版本。

'com.android.support.constraint:constraint-layout:2.0.0-alpha2'

我想对两个不同的按钮单击做出反应,并为每个按钮触发动画。我目前的方法是在MotionScene中设置两个Transitions,每个OnClick触发器。

问题是似乎只找到了第一个过渡。对于第二个,什么也没发生。我做错了什么,或者你能为每个MotionScene设置一个过渡吗?如果是这种情况,那么问题有不同的解决方案吗?

以下是我的运动场景的重要部分

<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto">
<Transition
motion:constraintSetStart="@id/startHome"
motion:constraintSetEnd="@id/endHome"
motion:duration="300">
<OnClick
motion:mode="toggle"
motion:target="@+id/imageView_bottom_home" />
</Transition>
<Transition
motion:constraintSetStart="@id/startSearch"
motion:constraintSetEnd="@id/endSearch"
motion:duration="300">
<OnClick
motion:mode="toggle"
motion:target="@+id/imageView_bottom_search" />
</Transition>
<ConstraintSet android:id="@+id/startSearch">
<Constraint
android:id="@id/imageView_bottom_search"
...startConstraints... />
</ConstraintSet>
<ConstraintSet android:id="@+id/endSearch">
<Constraint
android:id="@id/imageView_bottom_search"
...endConstraints... />
</ConstraintSet>
<ConstraintSet android:id="@+id/startHome">
<Constraint
android:id="@id/imageView_bottom_home"
...startConstraints... />
</ConstraintSet>
<ConstraintSet android:id="@+id/endHome">
<Constraint
android:id="@id/imageView_bottom_home"
...endConstraints... />
</ConstraintSet>

任何帮助表示赞赏。

此致敬意

我遇到了同样的问题。 我找到的解决方案是选择哪一个转换:

(在 Java 代码中(...

MotionLayout motionConteiner = findViewById(R.id.motion_container);
button1.setOnClickListener((v) -> {
motionConteiner.setTransition(R.id.start1, R.id.end1);
motionConteiner.transitionToEnd();//                
});
button2.setOnClickListener((v) -> {
motionConteiner.setTransition(R.id.start2, R.id.end2);
motionConteiner.transitionToEnd();//                
});

一个更kotlin'y的答案:

with(view as MotionLayout) {
setTransition(R.id.startState, R.id.endState)
transitionToEnd()
}

支持多个过渡。

在您共享的代码中,您有 4 个约束集,start_home -> end_home start_search -> end_search。 相反,只有 3 组,其中一组是基本状态,例如开始 -> end_home 和开始 -> end_search。这里的"开始"代表屏幕的基本状态

发生这种情况是因为,假设您先执行了主页操作,然后执行了搜索操作,则搜索将不起作用,因为起始条件 (start_search( 与start_home或end_home(最后应用(不匹配

我认为aba是对的。我在向单个场景文件添加多个过渡时也遇到问题。从理论上讲,MotionLayout 应该支持这一点,因为每个过渡都有一个单独的触发器(通常是单击或滑动(。也许这是MotionLayout的一个错误,需要修复。 根据我的经验,只关心场景文件中遇到的第一个过渡。 所以,目前,我认为没有办法在布局描述(场景(中支持多个过渡。更具体地说,所有运动都需要使用相同的触发器启动一次。

在我看来,MotionLayout只支持一个Transition,当您向MotionScene文件添加第二个Transition时,第二个Transition似乎被忽略了。但是,您可以在布局中有多个 MotionLayout,并为每个MotionLayout创建一个MotionScene。这也将使MotionScene文件更干净,并允许更易于维护。

在布局文件中,您需要一个可以包含多个MotionLayout文件的父布局。

<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
...
</data>
<!-- [databinding] {"msg":"Only one layout element with 1 view child is allowed. So a Parent Layout is required for Multiple motion layouts. -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.motion.widget.MotionLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="@xml/motion_scene_01"
tools:context=".menu.contextual.FragmentContextualOne"
tools:showPath="true">
<Button
android:id="@+id/btn_one"
android:layout_width="64dp"
android:layout_height="64dp"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="310dp" />
</androidx.constraintlayout.motion.widget.MotionLayout>
<androidx.constraintlayout.motion.widget.MotionLayout
android:id="@+id/m2"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="@xml/motion_scene_02">
<Button
android:id="@+id/btn_two"
android:layout_width="64dp"
android:layout_height="64dp"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="500dp" />
</androidx.constraintlayout.motion.widget.MotionLayout>
</FrameLayout>
</layout>

动作场景一。

<?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">
<Transition
android:id="@+id/transition_sine_wave"
motion:constraintSetStart="@+id/wave_start"  
motion:constraintSetEnd="@+id/wave_end"
motion:duration="2000"
motion:motionInterpolator="linear">
<OnClick
motion:touchAnchorId="@+id/btn_one"
motion:touchAnchorSide="right"
motion:targetId="@+id/btn_one"/>
</Transition>
<ConstraintSet android:id="@+id/wave_start">
<Constraint
android:id="@+id/btn_one"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintStart_toStartOf="parent"/>
</ConstraintSet>
<ConstraintSet android:id="@+id/wave_end">
<Constraint
android:id="@+id/btn_one"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginEnd="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
</MotionScene>

动作场景二

<?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">
<Transition
android:id="@+id/transition_straight"
motion:constraintSetEnd="@+id/right_end"
motion:constraintSetStart="@+id/left_start"
motion:duration="2000"
motion:motionInterpolator="linear" >
<OnClick
motion:targetId="@+id/btn_two"
motion:clickAction="toggle"/>
</Transition>
<ConstraintSet android:id="@+id/left_start">
<Constraint
android:id="@+id/btn_two"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="8dp"
android:layout_marginBottom="100dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintStart_toStartOf="parent" />
</ConstraintSet>
<ConstraintSet android:id="@+id/right_end">
<Constraint
android:id="@+id/btn_two"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginEnd="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent" />
</ConstraintSet>
</MotionScene>

这是我能想到的唯一 XML 解决方案。

最新更新