gpt4 book ai didi

Android MotionLayout 运动交错

转载 作者:行者123 更新时间:2023-12-04 14:45:35 24 4
gpt4 key购买 nike

我试图让我的 View 使用 MotionLayout 进行动画处理,但希望某些约束在其他约束之前进行动画处理。我认为这是motion的目的:Transition 的交错属性,但我不明白它是如何工作的,也没有任何地方成功工作的例子。随着 MotionLayout 的更新版本,我们似乎应该为各个约束设置 motion:motionStagger 但我似乎无法让它按需要交错。我能找到的唯一文档是 here解释增强型交错 API,但我不明白如何使用它。

我在下面添加了我的 MotionLayout 代码。作为引用,我使用的是 2.0.0-beta3' 版本的 ConstraintLayout

<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto">
<Transition
motion:constraintSetEnd="@+id/end"
motion:constraintSetStart="@+id/start"
motion:duration="300"
motion:motionInterpolator="easeInOut"
motion:staggered="0.4" />

<ConstraintSet android:id="@+id/start">
<Constraint android:id="@id/translucentOverlay">
<Layout
android:layout_width="5dp"
android:layout_height="5dp"
motion:layout_constraintBottom_toBottomOf="@id/imageBorder"
motion:layout_constraintEnd_toEndOf="@id/imageBorder"
motion:layout_constraintStart_toStartOf="@id/imageBorder"
motion:layout_constraintTop_toTopOf="@id/imageBorder" />
<CustomAttribute
motion:attributeName="alpha"
motion:customFloatValue="0.0" />
<Motion motion:motionStagger="2" />
</Constraint>

<Constraint android:id="@id/imageBorder">
<Layout
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
<CustomAttribute
motion:attributeName="crossfade"
motion:customFloatValue="0" />
<Motion motion:motionStagger="2" />
</Constraint>

<Constraint android:id="@id/imageBackground">
<Layout
android:layout_width="32dp"
android:layout_height="32dp"
motion:layout_constraintBottom_toBottomOf="@id/imageBorder"
motion:layout_constraintEnd_toEndOf="@id/imageBorder"
motion:layout_constraintStart_toStartOf="@id/imageBorder"
motion:layout_constraintTop_toTopOf="@id/imageBorder" />
<Motion motion:motionStagger="2" />
</Constraint>

<Constraint android:id="@id/profileInitialText">
<Layout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
motion:layout_constraintBottom_toBottomOf="@id/imageBackground"
motion:layout_constraintEnd_toEndOf="@id/imageBackground"
motion:layout_constraintStart_toStartOf="@id/imageBackground"
motion:layout_constraintTop_toTopOf="@id/imageBackground" />
<CustomAttribute
motion:attributeName="alpha"
motion:customFloatValue="1.0" />
<Motion motion:motionStagger="2" />
</Constraint>

<Constraint android:id="@id/profileImage">
<Layout
android:layout_width="32dp"
android:layout_height="32dp"
motion:layout_constraintBottom_toBottomOf="@id/imageBackground"
motion:layout_constraintEnd_toEndOf="@id/imageBackground"
motion:layout_constraintStart_toStartOf="@id/imageBackground"
motion:layout_constraintTop_toTopOf="@id/imageBackground" />
<Motion motion:motionStagger="2" />
</Constraint>

<Constraint android:id="@id/name">
<Layout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="128dp"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
<CustomAttribute
motion:attributeName="alpha"
motion:customFloatValue="0.0" />
<Motion motion:motionStagger="5" />
</Constraint>

<Constraint android:id="@id/description">
<Layout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toBottomOf="@id/name" />
<CustomAttribute
motion:attributeName="alpha"
motion:customFloatValue="0.0" />
<Motion motion:motionStagger="5" />
</Constraint>
</ConstraintSet>

<ConstraintSet android:id="@+id/end">
<Constraint android:id="@id/translucentOverlay">
<Layout
android:layout_width="match_parent"
android:layout_height="match_parent" />
<CustomAttribute
motion:attributeName="alpha"
motion:customFloatValue="1.0" />
<Motion motion:motionStagger="2" />
</Constraint>

<Constraint android:id="@id/imageBorder">
<Layout
android:layout_width="88dp"
android:layout_height="88dp"
motion:layout_constraintBottom_toBottomOf="@id/imageBackground"
motion:layout_constraintEnd_toEndOf="@id/imageBackground"
motion:layout_constraintStart_toStartOf="@id/imageBackground"
motion:layout_constraintTop_toTopOf="@id/imageBackground" />
<CustomAttribute
motion:attributeName="crossfade"
motion:customFloatValue="1" />
<Motion motion:motionStagger="2" />
</Constraint>

<Constraint android:id="@id/imageBackground">
<Layout
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_marginTop="64dp"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
<Motion motion:motionStagger="2" />
</Constraint>

<Constraint android:id="@id/profileInitialText">
<Layout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
motion:layout_constraintBottom_toBottomOf="@id/imageBackground"
motion:layout_constraintEnd_toEndOf="@id/imageBackground"
motion:layout_constraintStart_toStartOf="@id/imageBackground"
motion:layout_constraintTop_toTopOf="@id/imageBackground" />
<Motion motion:motionStagger="2" />
<CustomAttribute
motion:attributeName="alpha"
motion:customFloatValue="0.0" />
</Constraint>
<Constraint android:id="@id/profileImage">
<Layout
android:layout_width="70dp"
android:layout_height="70dp"
motion:layout_constraintBottom_toBottomOf="@id/imageBackground"
motion:layout_constraintEnd_toEndOf="@id/imageBackground"
motion:layout_constraintStart_toStartOf="@id/imageBackground"
motion:layout_constraintTop_toTopOf="@id/imageBackground" />
<Motion motion:motionStagger="2" />
</Constraint>

<Constraint android:id="@id/name">
<Layout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toBottomOf="@id/profileImage" />
<CustomAttribute
motion:attributeName="alpha"
motion:customFloatValue="1.0" />
<Motion motion:motionStagger="5" />
</Constraint>

<Constraint android:id="@id/description">
<Layout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toBottomOf="@id/name" />
<CustomAttribute
motion:attributeName="alpha"
motion:customFloatValue="1.0" />
<Motion motion:motionStagger="5" />
</Constraint>
</ConstraintSet>

最佳答案

好的,所以在搞砸了很长时间之后,经过大量的反复试验,并研究了 this 中给出的方程式发布更新,这是我想出的。

上面的链接文章为我们提供了一些有些令人困惑的方程式

Let
The motionStagger value is S(Vi)
The overall stagger value is stagger (from 0.0 - 1.0)
The duration of the animation is duration
The views animation duration = duration * (1 - stagger)
The view starts animating at duration * (stagger - stagger * (S(Vi) - S(V0)) / (S(Vn) - S(V0)))

确定过渡阶段值:

要确定您想要的整体错开情况,请考虑您尝试错开的观看次数。我在上面链接的文章指出 viewDuration = totalDuration*(1 - stagger)所以我们可以重新排列这个方程变成stagger = 1 - (viewDuration / totalDuration) .就我而言,由于我想在 View 进入时有三个不同的时刻,所以我想拥有我的 viewDuration / totalDuration1/3 .为了简化数学,我选择将我的交错设置为 0.6 ,使每个viewDuration 400。所以我的转换代码如下所示

<Transition
motion:constraintSetEnd="@+id/end"
motion:constraintSetStart="@+id/start"
motion:duration="1000"
motion:motionInterpolator="easeInOut"
motion:staggered="0.6" />

您会注意到我将持续时间增加到 1000 以更清楚地查看交错(一旦您确定了交错值,可以更新此处的持续时间,并且交错应适当缩放以适应时间范围)。

确定个人观点的交错值:

所以现在我们需要弄清楚将什么作为 ?在 <Motion motion:motionStagger="?" />

这就是数学变得非常复杂的地方。对于我们要设置交错的每个 View ,它们应该按交错值排序。我们给出的等式(经过修改以使其比文章更具可读性)是:

animationStartTime = totalDuration * (stagger - stagger * ((staggerCurrentView - lowestStaggerValue)/(highestStaggerValue - lowestStaggerValue))

这肯定有点复杂,但我可以用我的例子来分解它。

因此,对于我的示例,我们已经讨论了如何让三个 View 稍微均匀地错开(这就是我们选择 0.6 的错开值的原因)。我知道根据下面等式的逆结构,最高的 View motionStagger value 将首先动画化。

假设我们有三个 View ,一个我想排在第一位的 ImageView,一个我想排在第二位的 TextView,以及一个我想排在第三位的 Button。所以我会给 ImageView 分配一个motionStagger 值3,TextView 一个motionStagger 值2,TextView 一个motionStagger 值1。让我们在这里进行计算:

Stagger value = 0.6
motionStaggerValues = 3 (for ImageView), 2 (for TextView), and 1(for Button)
ImageView animationStartTime = 1000 * (0.6 - 0.6 * ((3-1)/(3-1)))
= 1000 * (0.6 - 0.6 * (1)) = 1000 * 0 = 0

所以 ImageView 从 0 开始动画并动画 400 毫秒(如上一节所示)。现在让我们计算一下TextView

Stagger value = 0.6
motionStaggerValues = 3 (for ImageView), 2 (for TextView), and 1(for Button)
TextView animationStartTime = 1000 * (0.6 - 0.6 * ((2-1)/(3-1)))
= 1000 * (0.6 - 0.6 * (1/2)) = 1000 * 0.3 = 300

所以 TextView 从 300 开始动画并持续 400 毫秒。

最后,我们来计算一下Button的开始时间:

Stagger value = 0.6
motionStaggerValues = 3 (for ImageView), 2 (for TextView), and 1(for Button)
TextView animationStartTime = 1000 * (0.6 - 0.6 * ((1-1)/(3-1)))
= 1000 * (0.6 - 0.6 * (0)) = 1000 * 0.6 = 600

所以 Button 从 600 开始动画并持续 400 毫秒。

这些值可以根据您选择的 motionStagger 值进行移动和交错。为了解释起见,我试图让它尽可能简单,但它可能会变得非常复杂,具体取决于您要完成的工作。这是我上面概述的示例的最终代码的样子。

<ConstraintSet android:id="@+id/start">
<Constraint android:id="@id/imageView">
...
<Motion motion:motionStagger="3" />
</Constraint>

<Constraint android:id="@id/textView">
...
<Motion motion:motionStagger="2" />
</Constraint>

<Constraint android:id="@id/button">
...
<Motion motion:motionStagger="1" />
</Constraint>
</ConstraintSet>

在哪里需要另一个并行 ConstraintSet为最终状态。

关于Android MotionLayout 运动交错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59537546/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com