12月04, 2019

MotionLayout入门

What is MotionLayout?

MotionLayout is a layout type that helps you manage motion and widget animation in your app. MotionLayout is a subclass of ConstraintLayout and builds upon its rich layout capabilities. As part of the ConstraintLayout library, MotionLayout is available as a support library and is backwards-compatible to API level 14.

MotionLayout bridges the gap between layout transitions and complex motion handling, offering a mix of features between the property animation framework, TransitionManager, and CoordinatorLayout.

引用自官方文档:Manage motion and widget animation with MotionLayout

通过阅读官方文档我们可以得知MotionLayout的一些信息:

  • MotionLayout是用来帮助开发者管理运动和组件动画的

  • MotionLayout是ConstraintLayout的子类

  • MotionLayout是ConstraintLayout 2.0库中提供的新类,也可作为支持库使用,并且向后兼容到API 14。

  • MotionLayout是为了弥合了布局过渡和复杂运动处理之间的鸿沟,在属性动画框架,TransitionManager和CoordinatorLayout之间提供了多种功能。

  • MotionLayout是完全声明式,我们可以用xml描述出任何复杂的效果

  • MotionLayout不支持嵌套子布局或者activity transition(如果您就有这样的需求,那还是乖乖的用TransitionManager吧)

  • 最后,官方建议不要把MotionLayout仅仅当做一个动效库来使用,它应该用于帮助用户了解您的应用程序在做什么,并表达品牌的个性和风格。

    参见Understanding motion

When to use it?

当我们学习一个新的东西的时候,“什么时候(情况下)使用它?”是一个很重要的问题。如果这个问题没想清楚,可能会引发一些不良的效果。

那么,什么时候去用MotionLayout呢?

Use MotionLayout when animating UI elements the user will interact with

当用户需要与有动效的UI元素交互时请使用MotionLayout

言外之意:

  1. 现有实现动效的方式就可以简单实现的就别折腾了,比如用以下方式
  1. 一些界面加载完就直接执行的复杂动画,直接用Gif或者视频搞定的也不需要
  2. 总结一下,别为了用MotionLayout而强行使用

Getting started

在开始使用MotionLayout之前我们需要准备以下几步。

1. Android Studio 4.0

MotionLayout编辑器仅支持4.0之上版本

2. 导入依赖

在您app的build.gradle文件添加ConstraintLayout 2.0的依赖。

  1. 如果你使用的是AndroidX

  2. dependencies {
        implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta3'
    }
    
  3. 如果你还没有迁移到AndroidX,则需要使用support 库

    dependencies {
        implementation 'com.android.support.constraint:constraint-layout:2.0.0-beta3'
    } 
    

3. 创建布局文件

创建完fragment_explore_motion_layout_part1.xml布局文件后,在Design模式下,右键点击布局或者Component Tree,选择菜单中的Convert to MotionLayout选项即可一步将布局转换为MotionLayout

我们再来看一下该布局的xml代码

为了使布局信息与运动描述分开,每个MotionLayout都会使用app:layoutDescription引用一个单独的MotionScene文件,这个文件放在res/xml文件夹。

下面来看一下生成的MotionScene文件:res/xml/fragment_explore_motion_layout_part1_scene.xml

4. MotionScene常见的标签及属性

  • Transition标签是用来定义运动的具体细节的

    常用的如下

    • constraintSetStart 定义运动的初始状态

      这可以是ConstraintSet的ID,也可以是布局。

      要指定ConstraintSet,请将此属性设置为@+id/constraintSetId

      要指定布局,请设置为@layout/layoutState

    • constraintSetEnd 定义运动的最终状态,取值同constraintSetStart

    • duration 定义运动的持续时间,以毫秒为单位,如不指定则使用默认值400ms

    • motionInterpolator 定义运动插补器

      • easeInOut 缓入缓出
      • easeIn 缓入
      • easeOut 缓出
      • linear 线性
      • bounce 弹跳效果
    • autoTransition 自动过渡

      • none 不运动
      • jumpToStart 直接跳到开始
      • jumpToEnd 直接跳到结束
      • animateToStart 执行动画到开始
      • animateToEnd 执行动画到结束
  • OnSwipe 指定用户在布局上滑动时要执行的操作。

    • touchAnchorId 通过滑动移动的视图的Id。
    • touchAnchorSide 用户滑动界面时MotionLayout将尝试在touchAnchorId指定的视图和用户手指之间保持恒定的距离。而此属性指定的是手指和view的那一侧保持恒定的距离,可取值有以下几个:
      • left
      • right
      • top
      • bottom
    • dragDirection 用户滑动动作的方向。如果设置了此属性,则此onSwipe仅适用于沿指定方向的滑动。可接受的值为
      • dragLeft 左滑
      • dragRight 右滑
      • dragUp 上滑
      • dragDown 下滑
  • OnClick 指定当用户点击特定视图时要执行的操作。单个Transition可以有多个OnClick节点,每个OnClick指定一个不同的目标视图,并在点击该视图时执行不同的操作。

    • targetId 当用户点击targetId指定的view时将会执行Transition

    • ClickAction 点击视图时执行的操作。支持的值为:

      • toggle

        切换状态,如果当前状态是start的话,执行动画到end状态;若当前状态是end状态,则执行动画到start状态。

      • transitionToStart 执行动画到start状态

      • transitionToEnd 执行动画到end状态

      • jumpToStart 直接跳转到start状态

      • jumpToEnd 直接跳转到end状态

  • KeyFrameSet

    指定运动序列过程中视图的位置和属性。默认情况下,运动会从初始状态进行到结束状态。通过使用,您可以构建更复杂的动作。 包含节点。这些节点中的每个节点都指定运动中特定点的目标视图的位置或属性。 MotionLayout从起点到这些中间点中的每一个,再到最终目的地,使视图平滑地动画化。

  • KeyPosition

    指定运动序列中特定时刻的视图位置。此属性用于调整运动的默认路径。

    • motionTarget

      要在运动过程中改变属性的视图的Id

    • framePosition

      指定视图在运动序列中何时具有此指定的属性。例如,framePosition = 50则代表视图运动到整个运动序列的50%处。

    • percentX percentY 指定视图应到达的位置。这两个属性需要配合keyPositionType才能确定具体位置。

    • keyPositionType

      指定如何解释percentX和percentY值。

      • parentRelative

        percentX和percentY是相对于父视图指定的。取值范围 0~1。

      • deltaRelative

        相对于视图在整个运动序列过程中移动的距离,指定了percentX和percentY。 X为横轴,Y为纵轴。在这两种情况下,0都是该轴视图的起始位置,而1是最终位置。

        Note:deltaRelative模式下,x,y坐标范围不是0~1。

        x<0 ----> 视图会定位到y轴的左侧。

        y<0 ----> 视图会定位到x轴的下方。

        x=1.5 ---> 代表视图定位到x轴方向start到end的横向距离1.5倍的位置

        y=1.5 ---> 代表视图定位到y轴方向start到end的垂直距离1.5倍的位置

      • pathRelative

        X轴是目标视图在路径范围内移动的方向,0为开始位置,1为最终位置。 Y轴垂直于X轴,正值位于路径的右侧,负值位于左侧;设置一个非零的Y百分比会导致视图的路径向X轴的左侧或者右侧偏转形成弧线。因此,视图的初始位置是(0,0),最终位置是(1,0)。

        很多文章包括官网对y轴的取值都是写的x轴的左侧为正值,右侧为负值,但我实际测试的结果却是相反的。希望读者都亲自尝试一下。

  • KeyAttribute

    指定运动序列中特定时刻的视图属性。您可以使用设置视图的任何标准属性。

    • alpha
    • visibility
    • elevation
    • rotation, rotationX, rotationY
    • translationX, translationY, translationZ
    • scaleX, scaleY
  • ConstraintSet

    为一个或多个节点指定开始或结束状态

关于更多的MotionScene标签以及它有哪些子标签可以查阅官方文档MotionLayout reference

Basic motion

下面这个栗子包含一个正方形的View,可以水平滑动。

Layout XML

MotionLayout的motionDegbug属性可以开启调试模式

  • motionDegbug
    • SHOW_PATH 展示运动路径
    • SHOW_PROGRESS 展示运动进度
    • SHOW_ALL 展示PATH&PROGRESS

MotionScene XML

  • KeyPosition

    framePosition=50处向y轴方向偏移50%

  • KeyAttribute

    framePosition=50处改变视图的如下属性:

    • 整体缩放2倍
    • X轴旋转-60°,y轴旋转45°
    • 透明度变为0.3

Custom attribute

下面使用ImageFilterView来演示自定义属性

Layout XML

MotionScene XML

Note:请注意,指定自定义属性时,自定义属性必须在start和end的ConstraintSet元素中成对出现,另外在运动过程中改变自定义属性时,也要保证前面的规则。

  • start中的初始自定义属性

    • roundPercent = 0.1 代表拥有10%的圆角

      取值范围[0~1],0代表正方形,1代表正圆。

    • crossfade = 0 展示src图片

      0=src,1=altsrc

  • end中的最终自定义属性

    • roundPercent = 1 正圆
    • crossfade = 1 展示altsrc图片

详情参见ImageFilterView

Summary

探索MotionLayout的Part1到此结束,本文主要介绍了一下MotionLayout是啥?啥时候用它?基础用法....

探索MotionLayout的Part2预计会实现一些更加复杂的效果。

关于本文顶部的效果参见MotionScene文件

Reference

本文链接:http://www.itzhouyang.com/post/explore_motion_layout_part1.html

-- EOF --

Comments