Просмотр утилизации в ListView с AnimationDrawable

Таким образом, у меня есть этот ListView с пользовательским адаптером, который позволяет мне "выбирать" элемент при щелчке элемента. Теперь у каждой строки списка есть ImageView, Drawable которого я заменяю на "выбранное" изображение, когда соответствующий элемент выбран. Работает нормально на моем устройстве Lollipop.

Я создаю Drawables в конструкторе адаптера списка

public DoubleRowSelectableArrayAdapter(Context context, int resource2, List<Recording> recordings) {
    super(context, resource2, recordings);

    idle = ContextCompat.getDrawable(context,R.drawable.idleicon);
    animation = (AnimationDrawable) ContextCompat.getDrawable(context, R.drawable.animation);
}

Теперь, как вы можете видеть, "выбранный" элемент - это AnimationDrawable, который должен воспроизводиться всякий раз, когда выбирается представление (кстати, это режим одиночного выбора).

Представления обновляются в методе getView

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    if (convertView == null) {
        LayoutInflater layoutInflater = LayoutInflater.from(getContext());
        convertView = layoutInflater.inflate(resource, null);
    }

    if (position == selection) {
        Log.d("getView", "selection = position");
        convertView.setSelected(true);
        convertView.setPressed(true);

        //get the imageview from the current row
        final ImageView pic = ((ImageView) convertView.findViewById(R.id.iconview));
        pic.setImageDrawable(animation);
    }
    else{
        Log.d("getView","else");
        convertView.setSelected(false);
        convertView.setPressed(false);

        //set idle icon
        ((ImageView) convertView.findViewById(R.id.iconview)).setImageDrawable(idle);
    }

Я бы предположил, что AnimationDrawable имеет "глобальное" состояние для всех элементов списка. Поэтому запуск анимации один раз в конструкторе должен позволять анимации воспроизводиться постоянно для каждого элемента списка.

Мне удалось запустить анимацию для каждого элемента, например, запустив ее в конструкторе или в методе getView с помощью вызова post(). Однако я пропустил эту часть кода, потому что хочу сосредоточиться на немного другой вещи.

Вот проблема: Когда я выбираю другой элемент списка во время воспроизведения анимации (oneshot=false), анимация вновь выбранного элемента будет воспроизводиться, если она находится НИЖЕ, как позиция старого элемента, НО НЕ воспроизводится, если она находится НАШЕ место старой позиции в список. Итак, я выбираю первый пункт. Анимация играет. Выбран второй элемент, воспроизводится анимация. Третий выбран, анимация воспроизводится...10-й элемент выбран, анимация воспроизводится. В другом направлении это не работает. Если у меня воспроизводится анимация 10-го элемента и я выбираю один из элементов с позициями 1-9, анимация не будет воспроизводиться вообще. Я должен был бы ждать окончания бегущей анимации, прежде чем сможет играть новая.

Это поведение меняется, если я получаю Drawable из ресурсов каждый раз, когда вызывается getView - тогда он работает абсолютно нормально. Так в getView

AnimationDrawable d = (AnimationDrawable) getContext().getResources().getDrawable(R.drawable.animation);
pic.setImageDrawable(d);
d.start(); //or by post() call, etc. -- however working.

Мое дикое предположение, что это как-то связано с переработкой View в списке. Что я должен сделать, чтобы сохранить (дорогой?) Экземпляр drawable из ресурсов в каждом вызове getView?

Вопросы: почему это так? Как правильно настроить анимацию? Разумно ли получать анимацию из ресурсов для каждого нового запуска анимации (вероятно, нет)? Как это сделать правильно?

1 ответ

Это почему? Всякий раз, когда воспроизводится анимация, за сценой генерируется поток, и значения применяются к целевому объекту. Этот поток синхронизирован, поэтому только один процесс может войти одновременно. Следовательно, вы должны создать отдельный объект анимации для каждого вида.

Как правильно настроить анимацию? Что я должен сделать, чтобы сохранить (дорогой?) Экземпляр drawable из ресурсов в каждом вызове getView? Разумно ли получать анимацию из ресурсов для каждого нового запуска анимации (вероятно, нет)? Как это сделать правильно? Вы делаете это правильно, вы должны создавать animationDrawable в каждом вызове getview(). Если вы хотите избавиться от создания drawable более одного раза (дорогая задача) для представления, установите animationDrawable в качестве тега и извлекайте его при каждом вызове getView и повторно инициализируйте, если оно равно нулю.

Я надеюсь, что вы получили свой ответ, если не дайте мне знать.

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