Как остановить анимацию (отмена () не работает)

245

Мне нужно остановить анимацию бегущего перевода. .cancel()Метод Animationне имеет никакого эффекта; анимация идет до конца в любом случае.

Как отменить анимацию бега?

Смешивание
источник

Ответы:

509

Звоните, clearAnimation()куда бы Viewвы ни позвонили startAnimation().

CommonsWare
источник
Но на самом деле мне нужна более сложная вещь: когда анимация останавливается, она должна оставаться в текущей позиции, т.е. у меня есть скользящее изображение и при касании событие должно зависать на этом месте. clearAnimation () - это не тот случай, потому что он сбрасывает состояние в начальную / конечную позицию в зависимости от setFillAfter ()
Mix
1
@ user349871: в любом случае, setFillAfter()вероятно, не делает то, что вы думаете. Когда происходит событие касания, очистите анимацию, а затем настройте макет, чтобы отразить любое постоянное изменение, которое вы ищете.
CommonsWare
Хорошо, я попытаюсь остановить анимацию, вызвав clearAnimation (). Следующий шаг - найти место, где была анимация, прежде чем я ее остановлю. Какой API для этого?
Mix
@Mix: для этого нет API.
CommonsWare
7
Привет еще раз! Я нашел способ получить точку (с точки зрения интерполированного времени), когда анимация была отменена. Вам нужно создать подкласс Animation и поместить туда код из анимации кода Android (например, TranslateAnimation). В вашем классе вы сможете сохранять и отслеживать положение в функции applyTransformation ().
Mix
40

В Android 4.4.4 кажется, что единственный способ остановить анимацию затухания альфа в представлении - это вызов View.animate().cancel()(т. Е. .cancel()Вызов в представлении ViewPropertyAnimator).

Вот код, который я использую для совместимости до и после ICS:

public void stopAnimation(View v) {
    v.clearAnimation();
    if (canCancelAnimation()) {
        v.animate().cancel();
    }
}

... с помощью метода:

/**
 * Returns true if the API level supports canceling existing animations via the
 * ViewPropertyAnimator, and false if it does not
 * @return true if the API level supports canceling existing animations via the
 * ViewPropertyAnimator, and false if it does not
 */
public static boolean canCancelAnimation() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
}

Вот анимация, которую я остановил:

v.setAlpha(0f);
v.setVisibility(View.VISIBLE);
// Animate the content view to 100% opacity, and clear any animation listener set on the view.
v.animate()
    .alpha(1f)
    .setDuration(animationDuration)
    .setListener(null);
Шон Барбо
источник
.setListener(null);это помогло мне.
Мухаммед Сакиб
18

Если вы используете слушателя анимации, установите v.setAnimationListener(null). Используйте следующий код со всеми параметрами.

v.getAnimation().cancel();
v.clearAnimation();
animation.setAnimationListener(null);
DJP
источник
2
Не обязательно звонить, v.setAnimation(null);потому что это будет сделано в v.clearAnimation();.
Кристиан
Как сказал @Christian v.setAnimation (null) не требуется
akshay bhange
5

Вы должны использовать .clearAnimation (); метод в потоке пользовательского интерфейса:

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        v.clearAnimation();
    }
});
rz0
источник
3

То, что вы можете попытаться сделать, это получить Матрицу преобразования из анимации, прежде чем остановить ее, и осмотреть содержимое Матрицы, чтобы получить значения позиций, которые вы ищете.

Вот API, которые вы должны посмотреть в

public boolean getTransformation (long currentTime, Transformation outTransformation)

public Matrix getMatrix ()

public void getValues (float[] values)

Так, например (некоторый псевдокод. Я не проверял это):

Transformation outTransformation = new Transformation();
myAnimation.getTransformation(currentTime, outTransformation);
Matrix transformationMatrix = outTransformation.getMatrix();
float[] matrixValues = new float[9];
transformationMatrix.getValues(matrixValues);
float transX = matrixValues[Matrix.MTRANS_X];
float transY = matrixValues[Matrix.MTRANS_Y];
Akos Cz
источник
Где мы можем получить currentTime?
Мако
О, в документации говорится, что они соответствуют «настенным часам», в другом месте они определяют настенные часы как System.currentTimeMillis (), что соответствует календарному времени и будет перескакивать всякий раз, когда время изменяется пользователем или сетью. Странная мера для использования.
Мако
0

Используйте метод setAnimation (null), чтобы остановить анимацию, он представлен как открытый метод в View.java , он является базовым классом для всех виджетов , которые используются для создания интерактивных компонентов пользовательского интерфейса (кнопок, текстовых полей и т. Д.). /** * Sets the next animation to play for this view. * If you want the animation to play immediately, use * {@link #startAnimation(android.view.animation.Animation)} instead. * This method provides allows fine-grained * control over the start time and invalidation, but you * must make sure that 1) the animation has a start time set, and * 2) the view's parent (which controls animations on its children) * will be invalidated when the animation is supposed to * start. * * @param animation The next animation, or null. */ public void setAnimation(Animation animation)

Саурабх Диллон
источник
0

Чтобы остановить анимацию, вы можете установить такой objectAnimator, который ничего не делает, например

сначала при ручном переключении анимация слева направо:

flipper.setInAnimation(leftIn);
flipper.setOutAnimation(rightOut);

тогда при переключении на автоматическое переключение нет анимации

flipper.setInAnimation(doNothing);
flipper.setOutAnimation(doNothing);

doNothing = ObjectAnimator.ofFloat(flipper, "x", 0f, 0f).setDuration(flipperSwipingDuration);
Андрей Глухов
источник