如何在整个翻译动画中实现均匀速度?
How to achieve uniform velocity throughout a Translate Animation?
我有一个无限翻译动画应用于 ImageView
:
Animation animation = new TranslateAnimation(0, 0, -500, 500);
animation.setDuration(4000);
animation.setFillAfter(false);
myimage.startAnimation(animation);
animation.setRepeatCount(Animation.INFINITE);
我注意到,当图像靠近起点和终点时,翻译过程比接近一半距离(中点)时要慢。
我想 android 上的平移动画速度不均匀。
如何使整个过程中的速度均匀?
我进行了一些源代码调查以对此进行调查。首先,请注意 if 线性插值器用于为 [=29 的 applyTransformation
方法提供 interpolatedTime
值=],生成的平移将具有恒定速度(因为偏移 dx
和 dy
是 interpolatedTime
的线性函数(第 149-160 行)):
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
float dx = mFromXDelta;
float dy = mFromYDelta;
if (mFromXDelta != mToXDelta) {
dx = mFromXDelta + ((mToXDelta - mFromXDelta) * interpolatedTime);
}
if (mFromYDelta != mToYDelta) {
dy = mFromYDelta + ((mToYDelta - mFromYDelta) * interpolatedTime);
}
t.getMatrix().setTranslate(dx, dy);
}
applyTransformation
由基础 Animation
class 的 getTransformation
方法调用(第 869-870 行):
...
final float interpolatedTime = mInterpolator.getInterpolation(normalizedTime);
applyTransformation(interpolatedTime, outTransformation);
...
根据 setInterpolator
方法的文档(第 382-392 行),mInterpolator
应默认为线性插值器:
/**
* Sets the acceleration curve for this animation. Defaults to a linear
* interpolation.
*
* @param i The interpolator which defines the acceleration curve
* @attr ref android.R.styleable#Animation_interpolator
*/
public void setInterpolator(Interpolator i) {
mInterpolator = i;
}
然而,这似乎是错误的:Animation
class 中的两个构造函数都调用了 ensureInterpolator
方法(第 803-811 行):
/**
* Gurantees that this animation has an interpolator. Will use
* a AccelerateDecelerateInterpolator is nothing else was specified.
*/
protected void ensureInterpolator() {
if (mInterpolator == null) {
mInterpolator = new AccelerateDecelerateInterpolator();
}
}
这表明默认插值器是 AccelerateDecelerateInterpolator
。这解释了您在问题中描述的行为。
为了真正回答您的问题,您似乎应该按如下方式修改代码:
Animation animation = new TranslateAnimation(0, 0, -500, 500);
animation.setInterpolator(new LinearInterpolator());
animation.setDuration(4000);
animation.setFillAfter(false);
myimage.startAnimation(animation);
animation.setRepeatCount(Animation.INFINITE);
我有一个无限翻译动画应用于 ImageView
:
Animation animation = new TranslateAnimation(0, 0, -500, 500);
animation.setDuration(4000);
animation.setFillAfter(false);
myimage.startAnimation(animation);
animation.setRepeatCount(Animation.INFINITE);
我注意到,当图像靠近起点和终点时,翻译过程比接近一半距离(中点)时要慢。
我想 android 上的平移动画速度不均匀。
如何使整个过程中的速度均匀?
我进行了一些源代码调查以对此进行调查。首先,请注意 if 线性插值器用于为 [=29 的 applyTransformation
方法提供 interpolatedTime
值=],生成的平移将具有恒定速度(因为偏移 dx
和 dy
是 interpolatedTime
的线性函数(第 149-160 行)):
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
float dx = mFromXDelta;
float dy = mFromYDelta;
if (mFromXDelta != mToXDelta) {
dx = mFromXDelta + ((mToXDelta - mFromXDelta) * interpolatedTime);
}
if (mFromYDelta != mToYDelta) {
dy = mFromYDelta + ((mToYDelta - mFromYDelta) * interpolatedTime);
}
t.getMatrix().setTranslate(dx, dy);
}
applyTransformation
由基础 Animation
class 的 getTransformation
方法调用(第 869-870 行):
...
final float interpolatedTime = mInterpolator.getInterpolation(normalizedTime);
applyTransformation(interpolatedTime, outTransformation);
...
根据 setInterpolator
方法的文档(第 382-392 行),mInterpolator
应默认为线性插值器:
/**
* Sets the acceleration curve for this animation. Defaults to a linear
* interpolation.
*
* @param i The interpolator which defines the acceleration curve
* @attr ref android.R.styleable#Animation_interpolator
*/
public void setInterpolator(Interpolator i) {
mInterpolator = i;
}
然而,这似乎是错误的:Animation
class 中的两个构造函数都调用了 ensureInterpolator
方法(第 803-811 行):
/**
* Gurantees that this animation has an interpolator. Will use
* a AccelerateDecelerateInterpolator is nothing else was specified.
*/
protected void ensureInterpolator() {
if (mInterpolator == null) {
mInterpolator = new AccelerateDecelerateInterpolator();
}
}
这表明默认插值器是 AccelerateDecelerateInterpolator
。这解释了您在问题中描述的行为。
为了真正回答您的问题,您似乎应该按如下方式修改代码:
Animation animation = new TranslateAnimation(0, 0, -500, 500);
animation.setInterpolator(new LinearInterpolator());
animation.setDuration(4000);
animation.setFillAfter(false);
myimage.startAnimation(animation);
animation.setRepeatCount(Animation.INFINITE);