如何在执行时减慢中间的动画?
How to slow down an animation in its middle while being executed?
由于问题已明确说明,我想在用户单击某个按钮时减慢正在执行的 TranslateAnimation。
这就是我实例化 TranslateAnim 的方式,其中 -textViewHeight
和 layoutHeight
只是我之前实例化的一些值:
从上到下。
TranslateAnim translateAnim = new TranslateAnim(0, 0, -textViewHeight, layoutHeight);
translateAnim.setDuration(20000);
translateAnim.setInterpolator(new LinearInterpolator());
textView.startAnimation(translateAnim);
这是我想要减慢 TranslateAnim 速度的方法:
虽然没有像我预期的那样工作。
public void slowDown() {
translateAnim.setStartTime(translateAnim.getStartTime() - 20000);
translateAnim.setDuration((20000 - translateAnim.getElapsedTime()) * 2);
}
我也试过了,但还是不行:
translateAnim.setInterpolator(new DecelerateInterpolator());
我的自定义 TranslateAnim class 扩展 TranslateAnimation:
public class TranslateAnim extends TranslateAnimation {
private long mElapsedAtPause, elapsedTime;
private boolean mPaused = false;
public TranslateAnim(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta) {
super(fromXDelta, toXDelta, fromYDelta, toYDelta);
}
@Override
public boolean getTransformation(long currentTime, Transformation outTransformation) {
if (mPaused && mElapsedAtPause == 0) {
mElapsedAtPause = currentTime - getStartTime();
}
if (mPaused) {
setStartTime(currentTime - mElapsedAtPause);
}
elapsedTime = currentTime - getStartTime();
return super.getTransformation(currentTime, outTransformation);
}
public long getElapsedTime() {
return elapsedTime;
}
public void slowDown() {
translateAnim.setStartTime(translateAnim.getStartTime() - 20000);
translateAnim.setDuration((20000 - translateAnim.getElapsedTime()) * 2);
}
public void pause() {
mElapsedAtPause = 0;
mPaused = true;
}
public void resume() {
mPaused = false;
}
@Override
public void cancel() {
super.cancel();
elapsedTime = 0;
mElapsedAtPause = 0;
mPaused = false;
}
}
有什么解决方法吗?
使用自定义插值器而不是线性插值器。线性的使它具有相等的时间片。自定义的可以把中间的时间片长一些。
例如:
public class CustomInterpolator implements Interpolator {
public boolean slowMode;
float lastInput;
float lastInputBeforeSlowed;
@Override
public float getInterpolation(float input) {
if (!slowMode) {
//Should be edited
lastInput = input;
return input;
} else {
return (input - lastInputBeforeSlowed) * .5f + lastInputBeforeSlowed;
}
}
public void enterSlowMode() {
slowMode = true;
lastInputBeforeSlowed = lastInput;
}
public void endSlowMode() {
slowMode = false;
//Should be edited
}
}
由于问题已明确说明,我想在用户单击某个按钮时减慢正在执行的 TranslateAnimation。
这就是我实例化 TranslateAnim 的方式,其中 -textViewHeight
和 layoutHeight
只是我之前实例化的一些值:
从上到下。
TranslateAnim translateAnim = new TranslateAnim(0, 0, -textViewHeight, layoutHeight);
translateAnim.setDuration(20000);
translateAnim.setInterpolator(new LinearInterpolator());
textView.startAnimation(translateAnim);
这是我想要减慢 TranslateAnim 速度的方法:
虽然没有像我预期的那样工作。
public void slowDown() {
translateAnim.setStartTime(translateAnim.getStartTime() - 20000);
translateAnim.setDuration((20000 - translateAnim.getElapsedTime()) * 2);
}
我也试过了,但还是不行:
translateAnim.setInterpolator(new DecelerateInterpolator());
我的自定义 TranslateAnim class 扩展 TranslateAnimation:
public class TranslateAnim extends TranslateAnimation {
private long mElapsedAtPause, elapsedTime;
private boolean mPaused = false;
public TranslateAnim(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta) {
super(fromXDelta, toXDelta, fromYDelta, toYDelta);
}
@Override
public boolean getTransformation(long currentTime, Transformation outTransformation) {
if (mPaused && mElapsedAtPause == 0) {
mElapsedAtPause = currentTime - getStartTime();
}
if (mPaused) {
setStartTime(currentTime - mElapsedAtPause);
}
elapsedTime = currentTime - getStartTime();
return super.getTransformation(currentTime, outTransformation);
}
public long getElapsedTime() {
return elapsedTime;
}
public void slowDown() {
translateAnim.setStartTime(translateAnim.getStartTime() - 20000);
translateAnim.setDuration((20000 - translateAnim.getElapsedTime()) * 2);
}
public void pause() {
mElapsedAtPause = 0;
mPaused = true;
}
public void resume() {
mPaused = false;
}
@Override
public void cancel() {
super.cancel();
elapsedTime = 0;
mElapsedAtPause = 0;
mPaused = false;
}
}
有什么解决方法吗?
使用自定义插值器而不是线性插值器。线性的使它具有相等的时间片。自定义的可以把中间的时间片长一些。
例如:
public class CustomInterpolator implements Interpolator {
public boolean slowMode;
float lastInput;
float lastInputBeforeSlowed;
@Override
public float getInterpolation(float input) {
if (!slowMode) {
//Should be edited
lastInput = input;
return input;
} else {
return (input - lastInputBeforeSlowed) * .5f + lastInputBeforeSlowed;
}
}
public void enterSlowMode() {
slowMode = true;
lastInputBeforeSlowed = lastInput;
}
public void endSlowMode() {
slowMode = false;
//Should be edited
}
}