为什么这个动画来回走动?

Why does this animation go back and forth?

我是 Android 的动画新手,我先进行一些测试。

所以,我创建了这个 Activity

  override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        button.setOnClickListener {
            imageView.animate()
                .translationX(imageView2.x - imageView.x)
                .translationY(imageView2.y - imageView.y)
                .start()
        }

    }

采用这种布局:

<ImageView
    android:id="@+id/imageView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="52dp"
    android:layout_marginTop="80dp"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:srcCompat="@mipmap/ic_launcher" />

<ImageView
    android:id="@+id/imageView2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="232dp"
    android:layout_marginTop="192dp"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:srcCompat="@android:drawable/ic_delete" />

<Button
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="144dp"
    android:layout_marginTop="296dp"
    android:text="Button"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

当我点击按钮时,它会将第一张图片完美地动画化为第二张图片。

我不明白的是为什么再次单击该按钮会使它以动画方式返回到其原始位置。 它似乎知道图像过去和现在的位置,并自行反转动画。

这实际上是合乎逻辑的,而且非常简单。

当您第一次点击时,imageView 转换为 [(232-52)x , (192-80)y] 即 (180, 112)。

然后当你第二次点击时,imageView从(180, 112)转换为[(232-180)x, (192-112)y]即(52,80)。

所以它 returns 回到原来的位置。

因为当您第二次调用动画时,imageView 的 X 和 Y 位置相同,因此差异为 0,translationX 和 translationY 重置为 0。

考虑一个具有易于推理的值的示例:

  • 第一个 ImageView 在 (50, 50)
  • 第二个 ImageView 在 (100, 100)

当您第一次按下按钮时,translationX 属性 将从其当前值 (0) 动画化为 100 - 50 = 50translationY 属性.

相同

"Translation" 是相对的。所以我们将平移添加到视图的原始坐标。 50 + 50 = 100,所以第一个视图滑到(100, 100),与第二个视图相同的位置。

  • 第一个 ImageView 位于 (100, 100),翻译值为 50 和 50。
  • 第二个 ImageView 仍在 (100, 100)

重要的是要认识到,第一个视图的 xy 属性已更新,但它们更新的 translationXtranslationY 属性 "remember"是非零的。所以现在第一个视图位于 (100, 100),但它记得它的翻译值为 50 和 50。

现在您再次单击该按钮。我们 运行 与之前的计算相同,但这次 translationX(和 y)的起始值不是零,它们是 50。因此 translationX 属性 将从其当前值 (50) 动画化为 100 - 100 = 0。本质上,我们是 "resetting" 将翻译值归零。所以视图滑回原来的位置。