【问题标题】:How to animate a line inside a View如何为视图内的线设置动画
【发布时间】:2020-10-31 09:28:39
【问题描述】:

我正在努力弄清楚为什么没有从 View1 的顶部动画到 View1 的底部。动画时它从底部开始动画,我不知道为什么。

这是我的布局。

....
    <View
        android:id="@+id/view_reader"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:background="@drawable/ic_view_finder"
        app:layout_constraintBottom_toBottomOf="@+id/surfaceView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:id="@+id/scannerBar"
        android:layout_width="280dp"
        android:layout_height="2dp"
        android:background="@color/colorAccent"
        app:layout_constraintBottom_toBottomOf="@+id/view_reader"
        app:layout_constraintEnd_toEndOf="@+id/view_reader"
        app:layout_constraintStart_toStartOf="@+id/view_reader"
        app:layout_constraintTop_toTopOf="@+id/view_reader"
        app:layout_constraintVertical_bias="0.0" />
...

所以我希望这个scannerBar 从 view_reader 的顶部开始动画,并在它到达 view_reader 的底部时重新开始。

我的动画如下:

val vto: ViewTreeObserver = binding.scannerBar.viewTreeObserver
        val listener = ViewTreeObserver.OnGlobalLayoutListener {

            val destinationScanView = (binding.viewReader.y +
                    binding.viewReader.height)
            ObjectAnimator.ofFloat(
                binding.scannerBar, "translationY",
                binding.viewReader.y,
                destinationScanView
            ).apply {
                repeatMode = ValueAnimator.REVERSE
                repeatCount = ValueAnimator.INFINITE
                interpolator = AccelerateDecelerateInterpolator()
                duration = 3000
            }.start()

        }
        vto.addOnGlobalLayoutListener(listener)

我错过了什么?有没有比这更简单的动画视图的方法?

编辑

简单的问题:如何使用translationYscannerBar(View)从view_reader(View)的顶部到view_reader(View)的底部进行动画处理?

MotionLayout 更容易吗?

【问题讨论】:

  • 请用更多代码和 xml 更具体地说明您的问题。我不确定您的问题是什么。
  • 我只想将 scanBanner 视图从 view_reader 顶部动画到 view_reader 顶部
  • 为什么不使用 Path() val path = Path().apply { arcTo(0f, 0f, 1000f, 1000f, 270f, -180f, true) } val pathInterpolator = PathInterpolator(path)
  • 你能举个例子吗?我不熟悉 Path,如何将它分配给我的视图?

标签: java android kotlin android-animation android-motionlayout


【解决方案1】:

简单动画通过translationY:

view.setTranslationY(0);
view.animate().translationY(200).setDuration(500).start();

问题是您需要知道必须使用多少翻译。在不同的设备上,你会得到不同的结果。

更好:

是的,使用运动布局会更直观,因为您只需要调整约束而无需担心任何相对平移Y。

<ConstraintSet android:id="@+id/start">
    <Constraint android:id="@+id/scannerBar"
        android:layout_width="280dp"
        android:layout_height="2dp"
        android:background="@color/colorAccent"
        app:layout_constraintEnd_toEndOf="@+id/view_reader"
        app:layout_constraintStart_toStartOf="@+id/view_reader"
        app:layout_constraintTop_toTopOf="@+id/view_reader"/>
    <Constraint android:id="@+id/view_reader"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:background="@drawable/ic_view_finder"
        app:layout_constraintBottom_toBottomOf="@+id/surfaceView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>
</ConstraintSet>

<ConstraintSet android:id="@+id/end">
    <Constraint android:id="@+id/scannerBar"
        android:layout_width="280dp"
        android:layout_height="2dp"
        android:background="@color/colorAccent"
        app:layout_constraintBottom_toBottomOf="@+id/view_reader"
        app:layout_constraintEnd_toEndOf="@+id/view_reader"
        app:layout_constraintStart_toStartOf="@+id/view_reader"/>
    <Constraint android:id="@+id/view_reader"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:background="@drawable/ic_view_finder"
        app:layout_constraintBottom_toBottomOf="@+id/surfaceView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>
</ConstraintSet>

<Transition
    android:id="@+id/transition"
    app:constraintSetEnd="@id/end"
    app:constraintSetStart="@+id/start"
    app:autoTransition="none"
    app:duration="1000"/>

有了这个scene1.xml,它将从顶部移动到底部!因为一开始就约束到顶部,最后约束到底部。

如何设置:

在您的布局文件中,将 motionLayout 作为您要设置动画的视图的父级!

<androidx.constraintlayout.motion.widget.MotionLayout
    android:id="@+id/motion_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/scene1"
    tools:context=".ui.YourFragment">

    <View
        android:id="@+id/view_reader"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:background="@drawable/ic_view_finder"
        app:layout_constraintBottom_toBottomOf="@+id/surfaceView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:id="@+id/scannerBar"
        android:layout_width="280dp"
        android:layout_height="2dp"
        android:background="@color/colorAccent"
        app:layout_constraintBottom_toBottomOf="@+id/view_reader"
        app:layout_constraintEnd_toEndOf="@+id/view_reader"
        app:layout_constraintStart_toStartOf="@+id/view_reader"
        app:layout_constraintTop_toTopOf="@+id/view_reader"
        app:layout_constraintVertical_bias="0.0" />

</androidx.constraintlayout.motion.widget.MotionLayout>

motionlayout 需要参数app:layoutDescription="@xml/scene1"。这是加载scene1.xml(位于res/xml/scene1.xml)的地方。当您更新布局时,AndroidStudio 会告诉您创建场景文件并自动创建。然后你只需要填写它。

如何开始动画:

在你的片段中你可以调用

    MotionLayout mMotionLayout = findViewById(R.id.motion_layout);
    mMotionLayout.setTransition(R.id.transition);
    mMotionLayout.transitionToEnd();

查看此链接了解更多详情:
https://developer.android.com/training/constraint-layout/motionlayout

【讨论】:

  • 我应该如何实现这个?你能解释一下我必须在哪里粘贴这个吗? scene.xml 是什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-26
  • 2013-09-25
  • 2013-11-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多