Попытка сброса значений из 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 теперь поддерживает поиск и воспроизведение в обратном направлении. Поиск позволяет установить положение анимации на определенный момент времени. Воспроизведение в обратном направлении полезно, если ваше приложение содержит анимацию для действий, которые можно отменить. Вместо того, чтобы определять два отдельных набора анимации, вы можете воспроизводить один и тот же в обратном порядке.

Другие вопросы по тегам