16

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

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

我想对两个不同的按钮单击做出反应并为每个按钮触发一个动画。我目前的方法是在每个TransitionsMotionScene设置两个触发器。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>

任何帮助表示赞赏。

此致

4

5 回答 5

14

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

(在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();//                
        });
于 2018-10-27T04:51:25.963 回答
0

支持多个转换。

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

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

于 2021-09-01T07:34:16.877 回答
0

一个更科特林的答案:

with(view as MotionLayout) {
    setTransition(R.id.startState, R.id.endState)
    transitionToEnd()
}
于 2020-04-16T10:33:50.153 回答
0

在我看来,MotionLayout仅支持 one Transition,当您TransitionMotionScene文件中添加一秒时,第二个Transition似乎被忽略了。但是,您可以在布局中有多个 MotionLayout,并MotionScene为每个MotionLayout. 这也将保持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 解决方案。

于 2020-11-04T17:03:50.817 回答
0

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

于 2019-11-15T20:04:06.840 回答