可以使用具有不同过渡的运动布局吗?

时间:2018-10-24 14:27:46

标签: android

我试图根据单击的按钮在不同位置显示一个视图。 但是当我在其中使用两个时,MotionScene无法正常工作。

<MotionScene xmlns:motion="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
>

<Transition android:id="@+id/toTimePicker2"
motion:duration="500" motion:constraintSetStart="@layout/add_event_fragment" 
 motion:constraintSetEnd="@id/enableTimePicker2">
<OnClick motion:target="@+id/time_to" motion:mode="toggle"/>
</Transition>

<Transition android:id="@+id/toTimePicker1"
motion:constraintSetStart="@layout/add_event_fragment" 
motion:constraintSetEnd="@id/enableTimePicker1"
motion:duration="500">
<OnClick motion:target="@+id/time_from"
  motion:mode="toggle" />
 < /Transition >

有人知道如何通过运动布局实现它吗? 看起来我应该在代码中使用ConstraintSet,但是我只想知道Motion是否可以实现

4 个答案:

答案 0 :(得分:2)

从昨天开始回顾一下Android Dev Summit。.Alpha 3将支持运动布局状态。

Check this video整个视频值得一看,但影片中提到的ConstraintLayout Alpha 3则在视频中以36:50提及了运动布局状态。

答案 1 :(得分:2)

Google对他们的Google Developers medium blog发表了评论:

  

注意:可以在MotionScene中定义多个约束集,因此,如果您有一个多步运动,其中这些步是有效的“静止”状态,则可以使用它们代替关键帧。从状态到状态的转换必须在代码中完成(可用更改侦听器)。

所以我能够通过创建一个侦听器来做到这一点:

motion_layout.setTransitionListener(
    object : MotionLayout.TransitionListener {
        override fun onTransitionChange(p0: MotionLayout?, p1: Int, p2: Int, p3: Float) {
        }

        override fun onTransitionCompleted(motionLayout: MotionLayout?, currentId: Int) {
            if (currentId == R.id.two) {
                //if the 1st transition has been made go to the second one
                intro_motion_layout.setTransition(R.id.two, R.id.three)
                intro_motion_layout.transitionToEnd()
            }
        }
    }
)
intro_motion_layout.transitionToEnd()

然后在我的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
    motion:constraintSetStart="@+id/one"
    motion:constraintSetEnd="@+id/two"
    motion:duration="200"
    motion:interpolator="linear" />

<ConstraintSet android:id="@+id/one">
    <Constraint />
</ConstraintSet>

<ConstraintSet android:id="@+id/two">
    <Constraint />
</ConstraintSet>

<ConstraintSet android:id="@+id/three">
    <Constraint />
</ConstraintSet>

答案 2 :(得分:1)

经过数小时的尝试不同的尝试,我终于发现了为什么它对我不起作用。我知道这是有可能的,因为Google提供了一个具有多个转换https://github.com/googlesamples/android-ConstraintLayoutExamples/blob/multi_state/motionlayout/src/main/res/xml/scene_26.xml的示例。但是,无论我尝试了什么,只有xml文件中的第一个转换都可以工作。我最终意识到,为了使过渡正常工作,UI的当前状态必须与约束集中定义的过渡的开始或结束状态匹配。不仅如此,而且不能多次定义相同的约束集,这意味着,如果在初始屏幕上可能发生两个不同的过渡,则这两个过渡都需要共享约束集。

我创建了一个简单的示例,其中两个按钮随不同的翻译而移动。我在任何地方都找不到简单的示例,因此希望这对某些人有所帮助。正如您将在视频中看到的那样,当password: "{{ svn_pass }}" 文本移至右侧时,您无法将left to right文本移至底部,因为该状态未在过渡中定义。

最后,我遇到的最后一个难题是,似乎每个约束集似乎都必须包含属于过渡的每个视图,无论它是否在当前过渡中。否则,视图似乎只是随机移动。

enter image description here

这是布局:

top to bottom

这是MotionScene

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:showIn="@layout/activity_main"
        app:layoutDescription="@xml/motion_scene"
        tools:context=".MainActivity">

    <TextView
            android:id="@+id/left_to_right_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Left to right"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

    <TextView
            android:id="@+id/top_to_bottom_text"
            android:text="Top to bottom"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

</androidx.constraintlayout.motion.widget.MotionLayout>

答案 3 :(得分:1)

我遇到了一个类似的问题,其中我定义了 2 个转换: A -> B(将称为过渡 X) B -> C(将称为过渡 Y) 两者都在点击动画视图时触发。

在我的情况下,重要的是运动场景文件中的过渡顺序。首先定义的转换将首先执行。因此,如果转换 Y 定义在转换 X 之上,则只有 B -> C -> B 转换是可能的。 但是,在运动场景文件中将过渡 X 置于过渡 Y 上方时,以下过渡成为可能 - A -> B -> C -> B。

注意:A -> B 仍然只能执行一次。