原文
基于物理的运动是由武力驱动的。春天的力量是指导互动和运动的一种力量。弹簧力具有以下特性:阻尼和刚度。在基于弹簧的动画中,值和速度是基于每个帧上应用的弹簧力来计算的。
如果您希望应用程序的动画仅在一个方向上减速,请考虑使用基于摩擦的 投射动画 。
在基于弹簧的动画中,SpringForce 课程可让您自定义弹簧刚度,阻尼比和最终位置。只要动画开始,弹簧力就会更新每帧的动画值和速度。动画一直持续到弹簧力达到平衡。
例如,如果您在屏幕上拖动一个应用程序图标,然后通过将图标从手指上抬起来释放该图标,该图标就会被一种看不见的但熟悉的力量拖回原来的位置。
图1展示了一个类似的弹簧效果。圆圈中间的加号(+)表示通过触摸手势施加的力。
图1. Spring发布效果
为您的应用程序构建弹簧动画的一般步骤如下所示:
注意:只有当您需要对动画值更改进行每帧更新时,才应该注册更新侦听器。更新侦听器可防止动画在单独的线程上运行。
以下各节将详细讨论构建弹簧动画的一般步骤。
dependencies {
implementation 'com.android.support:support-dynamic-animation:27.1.1'
}
在SpringAnimation类,您可以为对象创建一个春天的动画。要创建一个弹簧动画,需要创建一个SpringAnimation 类的实例并提供一个对象,一个对象的属性,您想要动画,以及一个可选的最终弹簧位置,您希望动画休息。
注意:在创建弹簧动画时,弹簧的最终位置是可选的。但是,它必须在开始动画之前定义。
final View img = findViewById(R.id.imageView);
// Setting up a spring animation to animate the view’s translationY property with the final
// spring position at 0.
final SpringAnimation springAnim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y, 0);
通过改变视图对象中的实际属性,基于弹簧的动画可以在屏幕上激活视图。系统中提供以下视图:
本DynamicAnimation类提供了两个听众:OnAnimationUpdateListener 和OnAnimationEndListener。这些侦听器会侦听动画中的更新,例如动画值发生变化并且动画结束时。
如果要为多个视图设置动画效果以创建链接动画,则可以设置OnAnimationUpdateListener 每次当前视图属性发生更改时接收回调。回调通知其他视图根据当前视图属性中发生的更改更新其弹簧位置。要注册侦听器,请执行以下步骤
注意:您需要在动画开始之前注册更新侦听器。但是,只有在动画值更改需要每帧更新时,才应该注册更新侦听器。更新侦听器可防止动画在单独的线程上运行
// Creating two views to demonstrate the registration of the update listener.
final View view1 = findViewById(R.id.view1);
final View view2 = findViewById(R.id.view2);
// Setting up a spring animation to animate the view1 and view2 translationX and translationY properties
final SpringAnimation anim1X = new SpringAnimation(view1,
DynamicAnimation.TRANSLATION_X);
final SpringAnimation anim1Y = new SpringAnimation(view1,
DynamicAnimation.TRANSLATION_Y);
final SpringAnimation anim2X = new SpringAnimation(view2,
DynamicAnimation.TRANSLATION_X);
final SpringAnimation anim2Y = new SpringAnimation(view2,
DynamicAnimation.TRANSLATION_Y);
// Registering the update listener
anim1X.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {
// Overriding the method to notify view2 about the change in the view1’s property.
@Override
public void onAnimationUpdate(DynamicAnimation dynamicAnimation, float value,
float velocity) {
anim2X.animateToFinalPosition(value);
}
});
anim1Y.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {
@Override
public void onAnimationUpdate(DynamicAnimation dynamicAnimation, float value,
float velocity) {
anim2Y.animateToFinalPosition(value);
}
});
OnAnimationEndListener 通知动画结束。每当动画达到平衡或取消时,您都可以设置侦听器来接收回调。要注册侦听器,请执行以下步骤:
要分别停止接收动画更新回调和动画结束回调,调用removeUpdateListener() 和removeEndListener() 方法
要设置动画的起始值,请调用该 setStartValue() 方法并传递动画的起始值。如果您未设置起始值,则动画会将对象属性的当前值用作起始值
如果要将属性值限制在一定范围内,可以设置最小动画值和最大动画值。如果您为具有固有范围的属性(例如alpha(从0到1))制作动画,则它还有助于控制范围。
两种方法都会返回正在设置值的动画。
注意:如果您已设置起始值并定义了动画值范围,请确保起始值在最小值和最大值范围内。
开始速度定义了动画属性在动画开始时的变化速度。默认启动速度设置为每秒零像素。您可以使用触摸手势的速度或使用固定值作为起始速度来设置速度。如果您选择提供固定值,我们建议以每秒dp为单位定义值,然后将其转换为每秒像素。以每秒dp定义值允许速度独立于密度和形状因子。有关将值转换为每秒像素数的更多信息,请参阅 将每秒转换为每秒像素数 部分。
要设置速度,请调用该 setStartVelocity() 方法并以每秒像素为单位传递速度。该方法返回设置速度的弹力对象。
注意:使用 GestureDetector.OnGestureListener或 VelocityTracker类方法检索并计算触摸手势的速度。
final View img = findViewById(R.id.imageView);
final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);
…
// Compute velocity in the unit pixel/second
vt.computeCurrentVelocity(1000);
float velocity = vt.getYVelocity();
anim.setStartVelocity(velocity);
弹簧的速度必须以每秒像素为单位。如果您选择提供固定值作为速度的开始,请提供每秒dp的值,然后将其转换为每秒像素数。对于转换,请使用该类中的 applyDimension() 方法TypedValue。请参阅以下示例代码:
float pixelPerSecond = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpPerSecond, getResources().getDisplayMetrics());
的SpringForce类定义了吸气和setter方法对于每个弹簧特性,如阻尼比和刚度。要设置弹簧属性,重要的是检索弹簧力对象或创建一个可以在其上设置属性的自定义弹簧力。有关创建自定义弹簧力的更多信息,请参阅 创建自定义弹簧力 部分。
提示:在使用setter方法时,您可以创建一个方法链,因为所有setter方法都会返回弹簧力对象。
阻尼比描述了弹簧振动的逐渐减小。通过使用阻尼比,您可以定义振荡从一次反弹到下一次反射衰减的速度。有四种不同的方法可以防止春季潮湿:
要将阻尼比添加到弹簧,请执行以下步骤:
注意:阻尼比必须是非负数。如果将阻尼比设置为零,则弹簧永远不会到达静止位置。换句话说,它永远在摇摆。
系统中有以下阻尼比常数:
图2:高反弹
图3:中等反弹
图4:低反弹
图5:没有反弹
默认的阻尼比设置为DAMPING_RATIO_MEDIUM_BOUNCY。
final View img = findViewById(R.id.imageView);
final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);
…
//Setting the damping ratio to create a low bouncing effect.
anim.getSpring().setDampingRatio(DAMPING_RATIO_LOW_BOUNCY);
…
刚度定义了测量弹簧强度的弹簧常数。当弹簧不在静止位置时,坚硬的弹簧对连接的物体施加更大的力。要为弹簧添加刚度,请执行以下步骤:
注意:刚度必须是正数。
系统中有以下刚度常数:
图6:高刚度
图7:中等硬度
图8:低刚度
图9:非常低的刚度
默认刚度设置为STIFFNESS_MEDIUM。
final View img = findViewById(R.id.imageView);
final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);
…
//Setting the spring with a low stiffness.
anim.getSpring().setStiffness(STIFFNESS_LOW);
…
您可以创建自定义弹簧力来替代使用默认弹簧力。自定义弹簧力可让您在多个弹簧动画中共享相同的弹力实例。一旦创建了弹力,就可以设置阻尼比和刚度等属性。
创建一个SpringForce对象。
SpringForce force = new SpringForce();
通过调用相应的方法来分配属性。你也可以创建一个方法链。
force.setDampingRatio(DAMPING_RATIO_LOW_BOUNCY).setStiffness(STIFFNESS_LOW);
调用该setSpring() 方法将弹簧设置为动画。
setSpring(force);
有两种方法可以启动弹簧动画:通过调用 start()或调用 animateToFinalPosition() 方法。这两种方法都需要在主线程中调用。
animateToFinalPosition() 方法执行两项任务:
由于该方法更新弹簧的最终位置,并在需要时启动动画,所以您可以随时调用此方法来更改动画的过程。例如,在链式弹簧动画中,一个视图的动画取决于另一个视图。对于这样的动画,使用该animateToFinalPosition() 方法更为方便 。通过在链式弹簧动画中使用此方法,您无需担心下一个要更新的动画是否正在运行。
图10展示了一个链式弹簧动画,其中一个视图的动画依赖于另一个视图。
图10.链式弹簧演示
要使用该animateToFinalPosition() 方法,请调用该 animateToFinalPosition() 方法并传递弹簧的静止位置。您也可以通过调用该setFinalPosition() 方法来设置弹簧的静止位置 。
该start()方法不会立即将属性值设置为起始值。属性值在每个动画脉冲中发生变化,这发生在绘制过程之前。因此,这些更改会反映在下一个框架中,就像这些值立即设置一样。
final View img = findViewById(R.id.imageView);
final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);
…
//Starting the animation
anim.start();
…
您可以取消或跳至动画的结尾。在需要取消或跳过amiation结束时的理想情况是,当用户交互要求动画立即终止时。这主要是当用户突然退出应用程序或视图变得不可见时。
有两种方法可以用来终止动画。该cancel()方法终止动画的值。而 canSkipToEnd()方法则将动画跳到最终值,然后终止它。
在您终止动画之前,首先检查弹簧的状态非常重要。如果状态不受阻塞,动画将无法到达休息位置。要检查弹簧的状态,请调用该 canSkipToEnd()方法。如果弹簧被阻尼,则方法返回true,否则 false。
一旦你知道弹簧的状态,您可以通过使用终止动画 skipToEnd()的方法或 cancel()method.The cancel()方法 必须只能在主线程中调用。
注意:通常,该 skipToEnd()方法会导致视觉跳跃。
Lastest Update:2018.05.08
QQ:94297366
微信打赏:https://pan.baidu.com/s/1dSBXk3eFZu3mAMkw3xu9KQ
公众号推荐:
转载于:https://blog.51cto.com/4789781/2120984