Android Motion布局

时间:2020-02-23 14:29:04  来源:igfitidea点击:

在本教程中,我们将在Android应用程序中讨论和实现MotionLayout。

Android MotionLayout

约束布局2.0引入了Android MotionLayout。
想法是轻松创建类似于UI布局的交互式流体运动。

以前,我们曾经使用以下内容为应用程序中的组件制作动画。

  • PropertyAnimation
  • 动画矢量可绘制
  • 协调器布局
  • 布局过渡

Motion Layout旨在使动画制作变得更好,更容易。

要使用动作布局,请添加以下依赖项:

implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2'

可以使用MotionLayout代替ConstraintLayout。
这是因为MotionLayout具有ConstraintLayout的所有属性(并且还将看到更多!)。

MotionLayout包含三项核心内容:

  • 开始布局
  • 具有结尾约束的结尾布局
  • 运动场景

开始和结束布局是基本的xml布局。

运动场景是我们定义基础运动的地方。
我们在 <MotionScene标签内进行操作。

它可以包含Transition,ConstraintSet,KeyFrameSet,Touch Handling。

在本教程中,我们将重点介绍过渡和触摸处理。

让我们看一个示例android应用程序,在该应用程序中,我们将在按钮上实现滑动功能,在此基础上布局将交换其内容。
我们称其为SwipeToSwap应用程序

代码

下面给出了activity_main_start.xml布局的代码:

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

  <TextView
      android:id="@+id/textOne"
      android:text="Constraint Layout 2.0"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginTop="8dp"
      android:layout_marginStart="8dp"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintTop_toTopOf="parent"
      app:layout_constraintStart_toStartOf="parent"

  <Button
      android:id="@+id/button"
      android:text="SWIPE TO SWAP"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:clickable="false"
      android:layout_marginTop="16dp"
      android:layout_marginStart="8dp"
      android:layout_marginEnd="8dp"
      app:layout_constraintTop_toBottomOf="@+id/textOne"
      app:layout_constraintStart_toStartOf="parent"

  <TextView
      android:id="@+id/textTwo"
      android:text="Hello Motion Layouts"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginTop="16dp"
      android:layout_marginEnd="8dp"
      app:layout_constraintTop_toBottomOf="@+id/button"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintEnd_toEndOf="parent"

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

app:layoutDescription是我们在MotionLayout上设置运动场景的地方。

下面给出了" activity_main_end.xml"布局的代码。
它表示过渡后的结束状态。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="https://schemas.android.com/apk/res/android"
  xmlns:app="https://schemas.android.com/apk/res-auto"
  xmlns:tools="https://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".MainActivity">

  <TextView
      android:id="@+id/textTwo"
      android:text="Hello Motion Layout"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginTop="8dp"
      android:layout_marginStart="8dp"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintTop_toTopOf="parent"
      app:layout_constraintStart_toStartOf="parent"

  <Button
      android:id="@+id/button"
      android:text="SWIPE TO SWAP"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:clickable="false"
      android:layout_marginTop="16dp"
      android:layout_marginStart="8dp"
      android:layout_marginEnd="8dp"
      app:layout_constraintTop_toBottomOf="@+id/textTwo"
      app:layout_constraintEnd_toEndOf="parent" 

  <TextView
      android:id="@+id/textOne"
      android:text="Constraint Layout 2.0"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginTop="16dp"
      android:layout_marginEnd="8dp"
      app:layout_constraintTop_toBottomOf="@+id/button"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintEnd_toEndOf="parent"

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

下面给出了" motion_scene.xml"文件的代码:

<?xml version="1.0" encoding="utf-8"?>
<MotionScene
  xmlns:motion="https://schemas.android.com/apk/res-auto">

  <Transition
      motion:constraintSetStart="@layout/activity_main_start"
      motion:constraintSetEnd="@layout/activity_main_end"
      motion:duration="1000">

      <OnSwipe
          motion:touchAnchorId="@id/button"
          motion:touchAnchorSide="top"
          motion:dragDirection="dragRight"

  </Transition>

  <Transition
      motion:constraintSetStart="@layout/activity_main_end"
      motion:constraintSetEnd="@layout/activity_main_start"
      motion:duration="1000">

      <OnSwipe
          motion:touchAnchorId="@id/button"
          motion:touchAnchorSide="top"
          motion:dragDirection="dragLeft"

  </Transition>

</MotionScene>

OnSwipe是在UI组件上执行的一种手势。
UIComponent与滑动方向一起在touchAnchorId中指定。

注意:还可以通过以下方式设置其他交互式手势,例如单击:

<OnClick
  app:target="@+id/button"
  app:mode="transitionToEnd"