「译」 MotionLayout 介绍 (Part IV) 深入理解关键帧

栏目: IOS · Android · 发布时间: 5年前

内容简介:MotionLayout 是一个来自 ConstraintLayout 2.0 的专注于动画的新布局。本系列的前几篇文章对该系统进行了很好的概述。我强烈建议你在阅读本文前先去查看它们。MotionLayout 动画系统通过在两种状态之间插入值(通常是控件的位置/大小)来工作,这些值是使用 ConstraintLayout 的约束系统 (ConstranitSets) 以及视图属性来指定的。这两种状态之间的转换也可以完全由触摸事件驱动。这个系统通常会为你的过渡提供很好的效果。除了上面说的状态之外,Motio

MotionLayout 是一个来自 ConstraintLayout 2.0 的专注于动画的新布局。本系列的前几篇文章对该系统进行了很好的概述。我强烈建议你在阅读本文前先去查看它们。

  • Introduction to MotionLayout ( part I )
  • 中文点这 Custom attributes, image transitions, keyframes ( part II )
  • 中文点这 Taking advantage of MotionLayout in your existing layouts (CoordinatorLayout, DrawerLayout, ViewPager) ( part III )

MotionLayout 动画系统通过在两种状态之间插入值(通常是控件的位置/大小)来工作,这些值是使用 ConstraintLayout 的约束系统 (ConstranitSets) 以及视图属性来指定的。这两种状态之间的转换也可以完全由触摸事件驱动。这个系统通常会为你的过渡提供很好的效果。

除了上面说的状态之外,MotionLayout 还支持关键帧(在本系列的第二部分中简单介绍过),我们将在本文中深入介绍这些关键帧。注意,虽然关键帧很好,但是它绝对是一个更专业的工具;你可能不需要或者偶尔才会用到。

请记住,在应用中添加的动画应该有它的意义;不要滥用!

但是,如果需要对你的过渡效果添加额外的功能,那么关键帧可以帮助你扩展 MotionLayout 的功能。如你所见,这里有很多内容需要覆盖:

上手关键帧(a Rendez-vous in Time)

从较高的层次上看,关键帧可以对你的两个状态之间的插值进行一个修改。

「译」 MotionLayout 介绍 (Part IV) 深入理解关键帧

MotionLayout 支持不同的关键帧:

KeyPosition
KeyAttribute
KeyCycle
KeyTimeCycle

注意,每种类型的关键帧都是独立于其他类型的关键帧的——也就是说,你不需要在相同的点上定义所有的关键帧(但是你不能在相同的点上定义相同类型的多个关键帧)

通用属性

所有关键帧(位置、属性、循环、周期)都有一些关键的通用属性:

motion:framePosition
motion:target
motion:transitionEasing
motion:curveFit

位置关键帧

位置关键帧可能是你最常使用到通用关键帧。它允许你修改控件在过渡期间在屏幕上的路径。举例,让我们在 MotionLayout 中为其中的一个控件做动画:

「译」 MotionLayout 介绍 (Part IV) 深入理解关键帧

我们有一个起始状态(左下)和结束状态(右上),过渡过程就是控件在这两种状态之间的线性 (linear interpoltion) 直线运动。

「译」 MotionLayout 介绍 (Part IV) 深入理解关键帧

通过引入位置关键帧,我们可以将运动路径变成曲线运动:

「译」 MotionLayout 介绍 (Part IV) 深入理解关键帧
「译」 MotionLayout 介绍 (Part IV) 深入理解关键帧

添加更多的关键帧允许你创建复杂的运动路径。

「译」 MotionLayout 介绍 (Part IV) 深入理解关键帧
<KeyFrameSet>
    <KeyPosition
        motion:keyPositionType="pathRelative"
        motion:percentX="0.75"
        motion:percentY="-0.3"
        motion:framePosition="25"
        motion:target="@id/button"/>
    <KeyPosition
        motion:keyPositionType="pathRelative"
        motion:percentY="-0.4"
        motion:framePosition="50"
        motion:target="@id/button"/>
    <KeyPosition
        motion:keyPositionType="pathRelative"
        motion:percentX="0.25"
        motion:percentY="-0.3"
        motion:framePosition="75"
        motion:target="@id/button"/>
</KeyFrameSet>
复制代码

什么是位置关键帧?

如果 ConstraintSets 已经允许你以非常灵活的方式摆放控件,那么你也许会问自己定位关键帧的意义是什么。原因如下:

  • 关键帧表示临时修改,而 ConstraintSets 表示“静止 (resting) ”状态
  • 关键帧在计算中相对于 ConstraintSet 更加轻量级
  • 位置关键帧允许你对一个控件的运动路径进行操纵 —— ConstraintSets 则是指定一个控件 相对 与其他控件的位置。

注意:在一个 MotionScene 中定义多个 ConstraintSets 是有可能的,所以如果你有一个多步骤的动作,其中这些步骤是有效的“静止”状态,那么你可以使用它们而不是关键帧。状态到状态的转换必须在代码中完成(可以使用改动监听器(change listeners))。

使用 XML 表示

关键帧存在于 <KeyFrameSet> 属性中, <KeyFrameSet> 则存在于 MotionScene 文件中的 <Transition> ,并且至少包含:

  • target : 被关键帧影响的控件
  • framePosition : 关键帧使用时机,(0-100)
  • keyPositionType : 所使用的坐标系 相对父容器(parentRelative), 三角定位(deltaRelative), 相对路径(pathRelative)
  • percentX / percentY :位置的 (x,y) 坐标
<Transition ...>
    <KeyFrameSet>
        <KeyPosition
            motion:keyPositionType="parentRelative"
            motion:percentY="0.25"
            motion:framePosition="50"
            motion:target="@+id/button"/>
    </KeyFrameSet>
</Transition>
复制代码

不同的坐标系

在 MotionLayout 中的起始状态和结束状态允许复杂的定位。对于 ConstraintSets,它们可以使用 ConstraintLayout 的所有功能。系统将根据密度 (density) 、屏幕方向(screen orientation)、语言(language) 等变化,正确的处理这些状态。

要使关键帧在这样的系统中发挥作用,我们需要它们能够以类似自适应的方式进行布局——而不是简单的使用固定的位置。

为了解决这个问题,同时保持关键帧系统的轻量级,我们提出了一种灵活的方法——在给定的坐标系中,每个关键帧的位置用(x,y)坐标对 (pair) 表示:

motion:percentX=”<float>”
motion:percentY=”<float>”

这个坐标的含义取决于所使用的坐标系类型: parentRelative , deltaRelative , or pathRelative .

注意:每个关键帧的位置都是单独存在——每个关键帧的位置都可以用它们自己相对的坐标系表示。

相对父容器(parentRelative)

坐标是根据相对父容器表示的。这是一种非常直接和直观的方式来表达关键帧的位置,通常就足够了。通常情况下,你用它来做与父容器相关的大范围运动。

「译」 MotionLayout 介绍 (Part IV) 深入理解关键帧

由于这个坐标系只基于父容器维度,而不是移动的控件的开始/结束位置,您可能会遇到这样的情况,即最后的关键帧位置以次优位置结束(相对于开始/结束位置)。(原文: you may encounter situations where the resulting keyframe position ends in a suboptimal position (relative to the start/end positions).)

三角定位(deltaRelative)

第二个坐标系通过使用开始/结束位置定义来解决这个问题。坐标表示起点和终点之间的百分比。

「译」 MotionLayout 介绍 (Part IV) 深入理解关键帧

和相对父容器坐标系有点像,这是一个相对直观的坐标系统,一般也会给出很好的结果。当你希望控件以水平或垂直运动开始或结束时,它十分有用。

它有一个潜在的问题——因为它是根据控件从开始到结束位置之间的差异定义的额,如果差异非常小(或者没有)关键帧将不会在对应轴上发生变化。例如,如果控件在屏幕从左向右移动,而保持在相同的高度,那么对位置关键帧使用 deltarelative percentY 将不会产生任何效果。

相对路径(pathRelative)

最后一个坐标系定义了一个相对于从开始状态到结束状态的直线路径。它可以解决 deltaRelative 坐标系中的问题——当一个控件没有在垂直轴移动的情况下,使用 pathRelative 将允许将位置关键帧设置为偏离路径。注意,它也支持负坐标。它是一个更特殊的坐标系,但是在处理时间上特别有用。下面有一个例子是实现一个曲线形状(比如“S”形),即使端点发生变化,它也会保持不变。

「译」 MotionLayout 介绍 (Part IV) 深入理解关键帧

Arc Motion

在 Material Design 中使用的一种典型的运动类型是圆弧运动(arc motion)。使用 MotionLayout 创建圆弧运动的一种方法是在起始位置和结束位置之间添加正确放置的位置关键帧,如前一节所述。

在 ConstraintLayout 2.0.0 alpha 2 中,我们引入了一种实现完美圆弧运动的新方案——而且它更加容易使用。你只需要将 motion:pathMotionArc 属性添加到起始的 ConstraintSet ,从而让默认的线形运动 (linear motion) 切换到弧线运动 (arc motion) 。

让我们来看一个简单的例子,开始状态是屏幕的右下,结束的位置是屏幕的顶部并且水平居中。添加下面这个属性就可以产生弧线运动:

motion:pathMotionArc=”startHorizontal”

「译」 MotionLayout 介绍 (Part IV) 深入理解关键帧

如果把属性换成:

motion:pathMotionArc=”startVertical”

就会改变弧线的方向:

「译」 MotionLayout 介绍 (Part IV) 深入理解关键帧

你仍然可以使用位置关键帧来创造更复杂的弧线路径。下面是结果:

「译」 MotionLayout 介绍 (Part IV) 深入理解关键帧

它是通过在动画中添加一个垂直居中的位置关键帧来实现的:

<KeyPosition
    motion:keyPositionType="parentRelative"
    motion:percentY="0.5"
    motion:framePosition="50"
    motion:target="@id/button"/>
复制代码

通过设置 motion:pathMotionArc 属性,还可以在该场景中使用关键帧来更改圆弧的方向。属性可以是 flip (翻转当前的圆弧方向)、 none (还原为线性运动),也可以是 startHorizontalstartVertical

「译」 MotionLayout 介绍 (Part IV) 深入理解关键帧
<KeyPosition
    motion:keyPositionType="parentRelative"
    motion:pathMotionArc="flip"
    motion:percentY="0.5"
    motion:framePosition="50"
    motion:target="@id/button"/>
复制代码
「译」 MotionLayout 介绍 (Part IV) 深入理解关键帧
<KeyPosition
    motion:keyPositionType="parentRelative"
    motion:pathMotionArc="none"
    motion:percentY="0.5"
    motion:framePosition="50"
    motion:target="@id/button"/>
复制代码

时间模型(Easing)

在前几节中,我们介绍了各种机制帮助你定义一个运动路径。对于一个动画,不仅仅需要选择合适的路径;时间也是至关重要的。

由于位置关键帧可以由时间指定,你可以使用它们来定义控件移动的快慢,具体取决于移动的空间。

但是在一个单独片段内——开始和结束状态之间,或者在关键帧之间——时间插值器是线形的。(the time interpolation is linear)

你可以使用 motion:transitionEasing 属性来指定一个缓和曲线来修改它。你可以将这个属性使用在 ConstraintSets 或 关键帧,它接受这些值:

  • cubic(float, float , float, float) , x1,y1,x2,y2 表示一个从 0,0 到 1,1 的三次贝塞尔方程的控制点
  • 或使用关键字: standard , accelerate , decelerate , 预定义的曲线类似 Material Design definitions.

标准曲线(Standard easing)

「译」 MotionLayout 介绍 (Part IV) 深入理解关键帧

通常用于在非触摸驱动的动画中。它最适合于开始和结束都是静止状态的元素。

加速曲线(Accelerate easing)

「译」 MotionLayout 介绍 (Part IV) 深入理解关键帧

加速通常用于一个元素移出屏幕。

减速曲线(Decelerate easing)

「译」 MotionLayout 介绍 (Part IV) 深入理解关键帧

减速通常用于一个元素进入屏幕。

键属性(KeyAttribute)

属性关键帧允许你在动画过程中指定控件的属性在给定时间点的更改——换句话说,它们与位置关键帧类似,但作用于属性而不是位置。

「译」 MotionLayout 介绍 (Part IV) 深入理解关键帧

上面的例子通过在 MotionScene 文件中添加 KeyAttribute 元素来实现:

<KeyFrameSet>
    <KeyAttribute
        android:scaleX="2"
        android:scaleY="2"
        android:rotation="-45"
        motion:framePosition="50"
        motion:target="@id/button" />
</KeyFrameSet>
复制代码

相比于 KeyPostion ,我们需要指定 framePosition (关键帧应用时机)和目标(哪个对象受到影响)。

支持的属性

一些你开箱即用的 View 属性:

android:visibility , android:alpha , android:elevation , android:rotation , android:rotationX , android:rotationY , android:scaleX , android:scaleY , android:translationX , android:translationY , android:translationZ

重点

受到应用程序的 SDK level 限制,其中一些属性将不起作用:

android:elevation
android:translationZ

自定义属性(Custom Attributes)

你可以通过添加 <CustionAttribute> 子节点在 ConstraintSets 和 KeyAttribute 节点中声明自定义属性。这个节点需要一个属性名( attributeName ),它是 getter/setter 的名称(除去set/get前缀)和要传入或使用的值类型,属性类型指定为下方其中一个:

customColorValue
customColorDrawableValue
customIntegerValue
customFloatValue
customStringValue
customDimension
customBoolean

举例,这面是对应上面动画的 XML:

<ConstraintSet android:id="@+id/start">
    <Constraint
        android:id="@+id/button" ...>
        <CustomAttribute
            motion:attributeName="backgroundColor"
            motion:customColorValue="#D81B60"/>
    </Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
    <Constraint
        android:id="@+id/button" ...>
        <CustomAttribute
            motion:attributeName="backgroundColor"
            motion:customColorValue="#9999FF"/>
    </Constraint>
</ConstraintSet>
复制代码

以上所述就是小编给大家介绍的《「译」 MotionLayout 介绍 (Part IV) 深入理解关键帧》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

移动的帝国

移动的帝国

曾航、刘羽、陶旭骏 / 浙江大学出版社 / 2014-1-1 / 48.00

日本是全世界移动互联网最发达的国家之一,堪称移动的帝国。在手机游戏、手机支付、移动医疗、移动电子商务、手机电视等方面,日本都充当了全球移动互联网的试验田。 曾经傲视全球的日本运营商将怎样面对转型的挑战?iPhone来势汹汹,如何打破封闭的日本移动互联网体系?日本在智能手机时代的手机游戏、O2O、移动医疗、移动广告等方面,涌现出了哪些值得借鉴的商业模式? 本书作者团队先后数次前往日本调研......一起来看看 《移动的帝国》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

html转js在线工具
html转js在线工具

html转js在线工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换