MotionLayout动画系统通过插入两个状态之间的值(通常是小部件的位置/大小)来工作,这两个状态使用ConstraintLayout的完整约束系统以及视图属性指定。这两种状态之间的转换也可以完全由触摸驱动。该系统通常会为您的过渡提供出色的结果。
除了状态之外,MotionLayout还支持关键帧 - 在本系列的第二部分中简要介绍- 我们将在本文中深入介绍。请注意,虽然关键帧很棒,但它绝对是一个更专业的工具; 你可能不需要的,或者只是偶尔需要的。
请记住,在应用程序中添加动作应该是有意义的; 不要过度!
但是,如果您需要额外的功能来定义转换,关键帧将扩展您可以使用MotionLayout执行的操作。正如您将看到的,有很多要涵盖的内容:
在较高级别,关键帧允许您在两个状态之间的插值期间的给定时间指定更改。
MotionLayout支持不同类型的关键帧:
请注意,每种类型的关键帧都独立于其他关键帧 - 也就是说,您不需要在同一点定义所有关键帧(但是您不能在同一点定义相同类型的多个关键帧)
所有关键帧(Position,Attribute,Cycle,TimeCycle)都有一些共同的属性:
位置关键帧可能是您将遇到或使用的最常见的关键帧。它们允许您在过渡期间修改窗口小部件在屏幕上的路径。例如,让我们采用MotionLayout(“父”)中包含的单个小部件的以下动画:
我们有一个开始(左下)和结束(右上)状态,运动路径只是这两个状态之间的线性插值 - 小部件将以直线移动。
通过引入位置关键帧,我们可以将运动路径更改为弯曲运动:
添加更多关键帧将允许您创建复杂的运动路径。
如果ConstraintSets已经允许您以非常灵活的方式定位窗口小部件,您可能会问自己,位置关键帧的重点是什么。有几个原因:
注意:可以在MotionScene中定义多个ConstraintSet,因此如果您有多步运动,其中这些步骤是有效的“静止”状态,则可以使用它们而不是关键帧。将状态转换为状态必须在代码中完成(更改侦听器可用)。
关键帧包含在
MotionLayout中的开始和结束状态允许复杂的定位。作为ConstraintSets,他们可以访问ConstraintLayout的全部功能。系统将正确处理这些状态的密度,屏幕方向,语言等的变化。
对于在这样的系统中有用的位置关键帧,我们需要它们能够以类似的自适应方式定位自己 - 我们不能简单地将它们定义为固定位置。
为了解决这个问题,同时保持关键帧系统的轻量级,我们提出了一种灵活的方法 - 每个关键帧的位置用给定坐标系中的(x,y)坐标对表示:
这些坐标的含义取决于所使用的坐标系统的类型:parentRelative,deltaRelative,或pathRelative。
注意:每个关键帧位置都是单独完成的 - 每个关键帧位置都可以使用自己的坐标系表示,与其他坐标系无关。
坐标相对于父容器表示。这是表达关键帧位置的非常简单直观的方式,通常就足够了。您通常会将此用于需要相对于容器的大型运动。
由于此坐标系仅基于父维度,而不是基于移动窗口小部件的开始/结束位置,因此您可能会遇到结果关键帧位置在次优位置(相对于开始/结束位置)结束的情况。
第二个坐标系通过使用开始/结束位置来定义这个确切的问题。坐标表示起始位置和结束位置之间距离的百分比。
类似地parentRelative,这是一个相对直观的坐标系,通常也会给出好的结果。当您希望窗口小部件以水平或垂直运动开始或结束时,它尤其有用。
它也存在一个潜在的问题 - 因为它是根据窗口小部件的开始和结束位置之间的差异定义的,如果差异非常小(或为零),关键帧的位置在受影响的轴上不会改变。例如,如果小部件在屏幕上从左向右移动,同时保持相同的高度,则使用deltaRelative percentY位置关键帧将无效。
该最后一个坐标系被定义为相对于起始状态和结束状态之间的直线路径。它确实解决了使用deltaRelative坐标系引起的问题- 即使在不在垂直轴上移动的小部件上,使用pathRelative也可以将位置关键帧设置为偏离路径。请注意,也支持负坐标。它是一个更专业的坐标系,但是在时间上特别有用。一个例子是实现即使端点改变也将保持不变的曲线形状(如“S”)。
材料设计中使用的典型运动类型是圆弧运动。使用MotionLayout创建弧形运动的一种方法是在开始位置和结束位置之间添加正确放置的位置关键帧,如上一节中所述。
在ConstraintLayout 2.0.0 alpha 2中,我们介绍了一种实现完美弧形运动的新方法 - 它更易于使用。你只需要加上 motion:pathMotionArc 属性到起始ConstraintSet,从默认线性运动切换到圆弧运动。
让我们看一个基本的例子,屏幕右下角的起始状态和屏幕顶部中间的结束状态。添加属性足以生成弧形运动:
motion:pathMotionArc=”startHorizontal”
motion:pathMotionArc=”startVertical”
将反转弧的起始方向:
您仍然可以使用位置关键帧来构建更复杂的弧形路径。结果如下:
通过在动画的中间添加一个垂直居中在屏幕上的关键帧来实现:
通过设置motion:pathMotionArc属性,该场景中的位置关键帧也可用于更改弧的方向。该属性可以是flip(翻转当前弧形方向),none(恢复为线性运动),也可以是显式startHorizontal或startVertical。
在前面的部分中,我们介绍了允许您定义运动路径的各种机制。虽然动画不仅仅是采取的路径; 时机至关重要。
由于位置关键帧是及时指定的,因此您可以使用它们来定义窗口小部件移动的速度或速度,具体取决于行进的空间。
但是在单个段内 - 在开始/结束状态之间或关键帧之间 - 时间插值是线性的。
您可以使用motion:transitionEasing属性指定缓动曲线来更改此设置。您可以在ConstraintSets或关键帧上应用此属性,它将继续应用。它可以采用以下值:
标准宽松
通常用于为非触摸驱动的动画添加角色。它最适用于开始和结束静止的元素。
加速宽松政策
当将元素移出场景时,通常使用加速。
减速宽松
在将元素移动到场景中时通常使用减速。
通过属性关键帧,您可以在动画期间指定给定时间点的窗口小部件属性更改 - 换句话说,它们与位置关键帧类似,但是处理属性而不是位置。
可以指定上面的示例KeyAttribute在MotionScene文件中添加以下元素:
至于KeyPosition,我们需要指定framePosition(当关键帧适用时)和target(对象受影响)。
您可以使用现成的属性是视图属性:android:visibility,android:alpha,android:elevation,android:rotation,android:rotationX,android:rotationY,android:scaleX,android:scaleY,android:translationX,android:translationY,android:translationZ
重要提示:根据您为应用程序定位的SDK级别,其中一些属性将不起作用:
您可以通过添加子
例如,这是与上述动画对应的XML:
本文介绍了MotionLayout中最常用的关键帧和路径规范。我们将在本系列的第五部分讨论KeyCycle和KeyTimeCycle关键帧,这是引入增加扰动的一个非常强大的方式(如波形),以属性(路径或基于时间的),允许各种有趣但可预见的循环效应(反弹,晃动,脉动等)。
文章代码地址