【和UI斗智斗勇的日子】MotionLayout——让人又爱又恨的布局(一)

MotionLayout是一种增强版布局控件,利用XML描述动画,可自动生成布局变换动画。它支持滑动和点击触发动画,结合ConstraintLayout的强大功能,用于实现复杂UI动画。本文介绍了基础使用方法,包括设置动画路径、编写MotionScene文件和触发动画选项。
摘要由CSDN通过智能技术生成

什么是MotionLayout

在2018 年 5 月发布的安卓 ConstraintLayout 2.0中,有这样一个新布局——MotionLayout。那么这个布局有什么用呢,在我看来,它的作用很像加强版的补间动画,你只需要提供给它开始和结束的xml布局文件,它就能自动帮你生成变换布局的动画,如下面安卓的官方示例图所示:
在这里插入图片描述
更为强大的是,它还支持滑动触发动画和点击触发动画两种方式,可以帮助我们实现复杂的用户界面动画和过渡效果,还是以安卓的示例图举例:
在这里插入图片描述
下面我们就来详细说说怎么使用这个神奇的布局控件。

简单使用

首先我们要简单了解下这个布局:

MotionLayout is a layout type that helps you manage motion and widget animation in your app. MotionLayout is a subclass of ConstraintLayout and builds on its rich layout capabilities. As part of the ConstraintLayout library, MotionLayout is available as a support library.
MotionLayout bridges the gap between layout transitions and complex motion handling, offering a mix of features between the property animation framework, TransitionManager, and CoordinatorLayout.
MotionLayout 是一种布局类型,可帮助您管理应用程序中的运动和小部件动画。 MotionLayout 是 ConstraintLayout 的子类,建立在其丰富的布局功能之上。作为 ConstraintLayout 库的一部分,MotionLayout 可作为支持库使用。
MotionLayout 弥合了布局转换和复杂运动处理之间的差距,提供了属性动画框架、TransitionManager 和 CoordinatorLayout 之间的混合功能。

根据安卓官方文档的介绍,我们可以知道MotionLayout其实是ConstraintLayout的子类,所以我们依然可以使用ConstraintLayout中控件的定位方式来写布局,这里我们先把MotionLayout当ConstraintLayout布局用,写一个变化前的界面:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/motionLayout"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:layoutDescription="@xml/activity_main_scene1_scene"
    app:showPaths="true">

    <TextView
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@color/black_333333"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        android:id="@+id/tv_show" />
</androidx.constraintlayout.motion.widget.MotionLayout>

可以看到,除了 app:layoutDescriptionapp:showPaths这两个属性外,其他的写法和ConstraintLayout基本一样,并且MotionLayout的子View也可以使用约束属性来调整位置。

我们先说app:showPaths这个属性,顾名思义,这个属性主要是展示MotionLayout的动画滑动轨迹,这里设置为true是为了方便调试。

app:layoutDescription这个属性需要传入一个布局文件,这个文件就是MotionLayout用来控制布局变换的关键所在,你可以通过android studio的提示来生成这个xml文件,也可以手动在res/xml目录下手动创建一个:

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

	//动画开始前控件位置
    <ConstraintSet android:id="@+id/start">
    	//每个控件的位置,通过id与上面xml中的控件关联
        <Constraint android:id="@id/tv_show" />
    </ConstraintSet>

	//动画结束时控件位置
    <ConstraintSet android:id="@+id/end">
        <Constraint android:id="@id/tv_show" />
    </ConstraintSet>

	//这里用来设置滑动还是点击触发变化
    <Transition
        app:constraintSetEnd="@id/end"
        app:constraintSetStart="@+id/start" >
    </Transition>
</MotionScene>

我们可以看到MotionScene文件主要由三部分构成,我们先说起始和结束位置中子View的写法:

<ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@id/tv_show"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent" />

    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@id/tv_show"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"/>
    </ConstraintSet>

可以看到写法和在约束布局中是基本一致的,我们只需要更改要变化的位置属性就可以了,下面重点说下Transition的用法:

    <Transition
        app:constraintSetEnd="@id/end"
        app:constraintSetStart="@+id/start"
        app:duration="1000">
        <OnSwipe
            app:dragDirection="dragStart"
            app:touchAnchorId="@id/tv_show"
            app:touchAnchorSide="bottom" />

        <OnClick
            app:clickAction="toggle"
            app:targetId="@id/tv_show"/>
    </Transition>

如上文代码所示,Transition有两种触发动画的方式,分别是滑动触发OnSwipe和点击触发OnClick

1、OnClick

通过 **app:duration=“1000”**来设置点击触发滑动后,动画时间

app:targetId:不用多说,设置点击哪个控件触发动画,通过id绑定。

app:clickAction有以下几个属性:
jumpToEnd——跳到结束位置,再次点击控件无法回到开始位置,
jumpToStart——跳到开始位置(要控件处于结束位置才有效),再次点击控件无法回到结束位置,
toggle——每次点击从当前位置滑动到相反的位置,
transitionToEnd——滑动到结束位置,再次点击控件无法回到开始位置,
transitionToStart——滑动到开始位置(要控件处于结束位置才有效),再次点击控件无法回到结束位置。

2、OnSwipe

app:touchAnchorId:设置拖动哪个控件触发动画,通过id绑定

app:dragDirection:设置拖动方向,有以下几个属性
dragAnticlockwise——逆时针拖动,很少使用,
dragClockwise——顺时针拖动,很少使用,
dragDown——向下托动,
dragEnd——向右拖动,
dragLeft——向左拖动,
dragRight——向右拖动,
dragStart——向左拖动,
dragUp——向上拖动,

touchAnchorSide: 跟踪手指的一侧(right / left / top / bottom)

了解了这些后,下面我们补全MotionScene 文件:

<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@id/tv_show"
            android:layout_width="50dp"
            android:layout_height="50dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent" />

    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@id/tv_show"
            android:layout_width="50dp"
            android:layout_height="50dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"/>
    </ConstraintSet>

    <Transition
        app:constraintSetEnd="@id/end"
        app:constraintSetStart="@+id/start"
        app:duration="1000">
        <OnSwipe
            app:dragDirection="dragStart"
            app:touchAnchorId="@id/tv_show"
            app:touchAnchorSide="start" />
    </Transition>
</MotionScene>

运行后,我们就实现了上面的第一个例子:
在这里插入图片描述

小结

通过上面的学习,相信大家也都了解到了MotionLayout的使用,其实MotionLayout还有关键帧等技术可以辅助实现功能,关于MotionLayout的使用也有很多优秀的文章可供参考,这里附下我学习时的文章,下节我们来讲下实际开发中MotionLayout的坑点,也就是的部分:

Android之MotionLayout(一),MotionLayout的基本使用

  • 29
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值