Как предотвратить мигание элемента RecyclerView после notifyItemChanged (pos)?

В настоящее время у меня есть просмотр recycler, данные которого обновляются каждые 5 секунд. Чтобы обновить данные в списке, я использую

notifyItemChanged(position);
notifyItemRangeChanged(position, mList.size());

Каждый раз, когда я вызываю notifyItemChanged(), элементы в моем обновлении просмотра recycler должным образом, однако, он будет мигать, потому что это вызывает onBindViewHolder для вызова снова. Так что, как будто это свежая нагрузка каждый раз. Как я могу предотвратить это, если это возможно?

Ответ 1

RecyclerView имеет встроенную анимацию, которая обычно добавляет приятный отточенный эффект. в вашем случае вы захотите отключить их:

((SimpleItemAnimator) mRecyclerView.getItemAnimator()).setSupportsChangeAnimations(false);

(Аниматор представления рециркулятора по умолчанию уже должен быть экземпляром SimpleItemAnimator)

Ответ 2

Вы можете отключить анимацию элементов.

mRecyclerView.setItemAnimator(null);

Ответ 3

Возможно, проблема не в анимации, а в нестабильном идентификаторе элемента списка.

Чтобы использовать стабильные идентификаторы, вам необходимо:

- setHasStableIds (true)
В RecyclerView.Adapter нам нужно установить setHasStableIds (true); Значение true означает, что этот адаптер будет публиковать уникальное значение в качестве ключа для элемента в наборе данных. Адаптер может использовать ключ, чтобы указать, что они совпадают или нет после уведомления об изменении данных.

- переопределить getItemId (int position)
Затем мы должны переопределить getItemId (int position), чтобы вернуть идентифицированный long для элемента в позиции. Нам нужно убедиться, что нет разных данных элемента с одинаковым возвращенным идентификатором.

Источник решения для этого здесь.

Ответ 4

Я прочитал приведенное ниже решение и реализовал его, и оно отлично работает на каждом тестируемом устройстве.

  • Клон Класс аниматора по умолчанию.
  • В методе animateChange() прокомментируйте ниже 3 строки,

    final float prevAlpha = oldHolder.itemView.getAlpha();
    .
    .
    oldHolder.itemView.setAlpha(prevAlpha);
    .
    .
    newHolder.itemView.setAlpha(0);
    
  • Настройте аниматор предметаайзера на свой клонированный класс.

//Примечание: я понимаю, как работает решение, не меняя альфа-значение нового держателя, но это не мое решение, я читал об этом непосредственно в stackoverflow, но по какой-то причине не смог его найти. Поделиться этим, чтобы помочь коллегам-разработчикам.

Ответ 5

Используйте stableId в вашем адаптере.

Вызовите adapter.setHasStableIds(true) и переопределите getItemId(int position) в своем классе адаптера.

Кроме того, верните некоторый уникальный идентификатор из getItemId(int position) для каждого элемента. Не просто верните позицию.