Попытка сброса значений из Property Animator для использования в представлении переработчика
Делали некоторую анимацию внутри строки в RecyclerView (а не в самой строке. Представьте, что вы расширяете текст), и бывают случаи, когда анимация просачивается в другие переработанные представления, в которых не должно быть этой анимации.
Так как я использую анимацию свойств, действие масштабирования изменяет размеры внутреннего вида, и утечка видна в 2 аспектах: 1) Анимация будет продолжаться (это я мог бы преодолеть с помощью некоторых охранников) 2) Вид был изменен и остановлен в своих треках и так это будет отражено в переработанном виде.
Как я могу восстановить вид в исходное состояние? Я перепробовал много подходов из постов, но ни один не решил. Самое близкое определение, которое я получил, было в этом посте без ответа: Как вернуть представление в исходное состояние после использования аниматоров для анимации некоторых его свойств?
Вот пример того, как я настроил свою анимацию в onBind (на этом есть попытка использовать onAnimationEnd, который я нашел в одном посте, но не работал)
ObjectAnimator scaleXUp = ObjectAnimator.ofFloat(mView, View.SCALE_X, 10f);
scaleXUp.setRepeatCount(ValueAnimator.INFINITE);
scaleXUp.setRepeatMode(ValueAnimator.REVERSE);
scaleXUp.setDuration(700);
ObjectAnimator scaleYUp = ObjectAnimator.ofFloat(mView, View.SCALE_Y, 10f);
scaleYUp.setRepeatCount(ValueAnimator.INFINITE);
scaleYUp.setRepeatMode(ValueAnimator.REVERSE);
scaleYUp.setDuration(700);
mTotalAnimation = new AnimatorSet();
mTotalAnimation.play(scaleXUp).with(scaleYUp);
mTotalAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
mTotalAnimation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
animation.removeListener(this);
animation.setDuration(0);
for(Animator va : ((AnimatorSet)animation).getChildAnimations()) {
((ValueAnimator)va).reverse();
}
}
});
mTotalAnimation.start();
И вот что я делаю в onUnbindData:
if (mTotalAnimation != null) {
mTotalAnimation.end();
mTotalAnimation = null;
}
И, как я видел, многим нравится подход clearAnimation - пытался и не работал.
1 ответ
4 дня и ни одного ответа, но пока что я решил сам. Таким образом, подход был близок, просто ошибочно.
Я добавил этот метод:
private void stopAnimation() {
for (Animator anim : mTotalAnimation.getChildAnimations()) {
((ObjectAnimator) anim).reverse();
anim.end();
}
}
и я называю это, когда я хочу сбросить представление.
Здесь я получаю анимацию от AnimatorSet и реверсирую и заканчиваю каждую. Я не понял, почему мне пришлось делать это вручную, но похоже, что эта возможность будет добавлена в Android O: https://developer.android.com/preview/api-overview.html
Начиная с Android O, API-интерфейс AnimatorSet теперь поддерживает поиск и воспроизведение в обратном направлении. Поиск позволяет установить положение анимации на определенный момент времени. Воспроизведение в обратном направлении полезно, если ваше приложение содержит анимацию для действий, которые можно отменить. Вместо того, чтобы определять два отдельных набора анимации, вы можете воспроизводить один и тот же в обратном порядке.