SpringAnimation is “physics-based motion driven by force”. An important part of this animation is a SpringForce that guides the interactivity and motion. It has two properties:

SpringAnimation是“ 受力驱动的基于物理的运动 ”。 该动画的重要部分是指导交互性和运动的SpringForce。 它具有两个属性:

  1. Damping — Reduction in the amplitude of an oscillation

    阻尼—减小振荡幅度

  2. Stiffness — Strength of the Spring

    刚度-弹簧的力量

This article will show how to use SpringAnimation for creating draggable views that, when released, bounces back to their original position.

本文将展示如何使用SpringAnimation创建可拖动视图,这些视图在发布时会反弹到其原始位置。

Lets get started!

让我们开始吧!

1.添加支持库 (1. Add the support library)

implementation 'androidx.dynamicanimation:dynamicanimation:1.1.0-alpha03'

2.创建一个自定义视图 (2. Create a custom view)

Create a view extending an AppCompatImageView, or any other choice of view depending on the requirements.

创建一个扩展AppCompatImageView,的视图AppCompatImageView,或者根据需要创建其他任何视图。

class BounceView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : AppCompatImageView(context, attrs, defStyleAttr) {
init {
...
}
}

2.1 Create SpringAnimation instances

2.1创建SpringAnimation实例

Since the end result is to handle the view x and y motion, two SpringAnimation instances need to be created, one for x and another for y.

由于最终结果是要处理视图xy运动,因此需要创建两个SpringAnimation实例,一个用于x ,另一个用于y

lateinit var animationX : SpringAnimation
lateinit var animationY : SpringAnimation

2.2 Add variables to save the original position

2.2添加变量以保存原始位置

To tug the view back to its original place, original coordinates need to be saved.

要将视图拖回其原始位置,需要保存原始坐标。

var originalX = 0f
var originalY = 0f

2.3 Use OnGlobalLayoutListener

2.3使用OnGlobalLayoutListener

The view needs to perform certain tasks once it has been laid out. ViewTreeObserver.OnGlobalLayoutListener can be utilised where its onGlobalLayout() callback can perform the tasks below:

布局后,视图需要执行某些任务。 ViewTreeObserver.OnGlobalLayoutListener可用于其中其onGlobalLayout()回调可以执行以下任务:

  • Initialise originalX and originalX (Step 2.4)

    初始化originalXoriginalX (步骤2.4)

  • Initialise animationX and animationY (Step 2.5)

    初始化animationXanimationY (步骤2.5)

  • Set up view’sOnTouchListener (Step 2.6)

    设置视图的OnTouchListener (步骤2.6)

viewTreeObserver.addOnGlobalLayoutListener(object :
ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() { //do tasks here viewTreeObserver.removeOnGlobalLayoutListener(this)
}
})

2.4 Initialise the original coordinates

2.4初始化原始坐标

The placement of a view can only be known when it has been drawn. The code below can be added to the observer attached in Step 2.3.

仅当绘制视图时才能知道视图的位置。 可以将以下代码添加到步骤2.3中附加的观察者中。

originalX = x
originalY = y

2.5 Initialise the SpringAnimation

2.5初始化SpringAnimation

Once the coordinates are known, SpringAnimation created in Step 2.1 can be initialised.

一旦知道坐标,就可以初始化在步骤2.1中创建的SpringAnimation。

fun createAnimationX() {
animationX = SpringAnimation(this, SpringAnimation.X).apply {spring = SpringForce().apply {finalPosition = originalXstiffness = SpringForce.STIFFNESS_MEDIUM
dampingRatio
= SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY}
}
}fun createAnimationY() {
animationY = SpringAnimation(this, SpringAnimation.Y).apply {spring = SpringForce().apply {finalPosition = originalYstiffness = SpringForce.STIFFNESS_MEDIUM
dampingRatio
= SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY}
}
}

SpringForce, as introduced in one of the earlier sections, has been used to specify the stiffness and dampingRatio of the animation by using Android’s predefined settings. The finalPosition refers to the final coordinate the view will animate to.

如先前部分之一所述, dampingRatio已用于通过使用Android的预定义设置来指定动画的stiffnessdampingRatio比。 最终finalPosition 是指视图将为其动画的最终坐标。

2.6 Enable dragging

2.6启用拖动

To handle any touch event that will drag the view, a OnTouchListener has to be implemented. It will, for basic dragging, handle two MotionEvents:

要处理将拖动视图的任何触摸事件,必须实现OnTouchListener 。 对于基本拖动,它将处理两个MotionEvent:

a. ACTION_DOWN:

一个。 ACTION_DOWN:

Triggered when the screen is first touched. deltaX and deltaY, that is the space between the view’s coordinate and the touch point’s coordinate, will be calculated here.

首次触摸屏幕时触发。 这里将计算deltaXdeltaY ,即视图坐标和触摸点坐标之间的空间。

b. ACTION_MOVE:

b。 ACTION_MOVE:

Triggered when the finger is moved across the screen. In order to drag the view with finger, either one of the following approaches can be used:

当手指在屏幕上移动时触发。 为了用手指拖动视图,可以使用以下方法之一:

  • Change view position using LayoutParams

    使用LayoutParams更改视图位置

  • Animate view to new x and y

    将视图动画化为新的xy

  • Change view position using setX and setY

    使用setXsetY更改视图位置

  • Change view position using translationX and translationY

    使用translationXtranslationY更改视图位置

This tutorial will implement drag using setX and setY .

本教程将使用setXsetY实现拖动。

var deltaX = 0f
var deltaY = 0f
var translateX = 0f
var translateY = 0fsetOnTouchListener(object : View.OnTouchListener {
override fun onTouch(view: View, event: MotionEvent?): Boolean {
when(event?.action) {
MotionEvent.ACTION_DOWN -> {
deltaX = view.x - event.rawXdeltaY = view.y - event.rawY}
MotionEvent.ACTION_MOVE -> {
translateX = deltaX + event.rawXtranslateY = deltaY + event.rawYview.x = translateX
view.y = translateY
}
}
return true
}
})

2.7 Bounce the View back to it’s original position

2.7将视图反弹回其原始位置

Up to this point, the view will move along with the finger/pointer. Upon releasing the view, it will remain in its current position. To bounce the view back to its original coordinates set in Step 2.4, one more MotionEvent needs to be handled:

到目前为止,视图将随手指/指针一起移动。 释放视图后,它将保持在当前位置。 要将视图反弹回其在步骤2.4中设置的原始坐标,还需要处理另一个MotionEvent:

a. ACTION_UP

一个。 ACTION_UP

Triggered when the gesture/touch ends. In this event, SpringAnimation initialised in Step 2.5 can be started.

当手势/触摸结束时触发。 在这种情况下,可以启动在步骤2.5中初始化的SpringAnimation。

MotionEvent.ACTION_UP -> {
animationX.start()
animationY.start()
}

3.将BounceView添加到片段/活动 (3. Add BounceView to Fragment/Activity)

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/containerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.photobook.springanimationapp.customview.BounceView
android:layout_width="80dp"
android:layout_height="80dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_android" />
</androidx.constraintlayout.widget.ConstraintLayout>

That is it! You can view the complete BounceView class here.

这就对了! 您可以在此处查看完整的BounceView类。

敬请关注 (Stay tuned)

Stay tuned as my next article will show how to utilise this BounceView for creating a floating view, similar to a chat-head, within an app.

请继续关注我的下一篇文章将展示如何利用这个BounceView创建浮动视图,类似于聊天头,一个应用程序

Image for post
Floating view like a chat-head within Photobook App
浮动视图像Photobook App中的聊天头

翻译自: https://medium.com/@ramsha_khan/bouncy-animation-with-androids-springanimation-x-and-y-1ab74289205

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐