У меня есть RecyclerView, который загружает некоторые данные из API, включает URL-адрес изображения и некоторые данные, и я использую networkImageView для ленивой загрузки изображения.
@Override
public void onResponse(List<Item> response) {
mItems.clear();
for (Item item : response) {
mItems.add(item);
}
mAdapter.notifyDataSetChanged();
mSwipeRefreshLayout.setRefreshing(false);
}
Вот реализация адаптера:
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, final int position) {
if (isHeader(position)) {
return;
}
// - get element from your dataset at this position
// - replace the contents of the view with that element
MyViewHolder holder = (MyViewHolder) viewHolder;
final Item item = mItems.get(position - 1); // Subtract 1 for header
holder.title.setText(item.getTitle());
holder.image.setImageUrl(item.getImg_url(), VolleyClient.getInstance(mCtx).getImageLoader());
holder.image.setErrorImageResId(android.R.drawable.ic_dialog_alert);
holder.origin.setText(item.getOrigin());
}
Проблема в том, что когда у нас есть обновление в recyclerView, оно вначале мигает очень короткое время, что выглядит странно.
Вместо этого я просто использовал GridView / ListView, и он работал так, как я ожидал. Сияния не было.
конфигурация для RecycleView в onViewCreated of my Fragment
:
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
mGridLayoutManager = (GridLayoutManager) mRecyclerView.getLayoutManager();
mGridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return mAdapter.isHeader(position) ? mGridLayoutManager.getSpanCount() : 1;
}
});
mRecyclerView.setAdapter(mAdapter);
Кто-нибудь сталкивался с такой проблемой? Что может быть причиной?
Ответы:
Попробуйте использовать стабильные идентификаторы в своем RecyclerView.Adapter
setHasStableIds(true)
и переопределитьgetItemId(int position)
.Без стабильных идентификаторов после
notifyDataSetChanged()
этого ViewHolders обычно назначаются не на одни и те же позиции. В моем случае это было причиной моргания.Здесь вы можете найти хорошее объяснение.
источник
Согласно этой странице проблемы .... это анимация изменения элемента recycleview по умолчанию ... Вы можете отключить ее ... попробуйте это
Изменить в последней версии
Цитата из блога разработчиков Android :
источник
Это просто сработало:
источник
code
ItemAnimator animator = recyclerView.getItemAnimator (); if (экземпляр аниматора SimpleItemAnimator) {((SimpleItemAnimator) аниматор) .setSupportsChangeAnimations (false); }code
У меня такая же проблема с загрузкой изображения с некоторых URL-адресов, а затем мигает imageView. Решено с помощью
вместо того
что позволяет избежать перезагрузки неизмененных старых данных.
источник
попробуйте это, чтобы отключить анимацию по умолчанию
это новый способ отключить анимацию, так как поддержка Android 23
этот старый способ будет работать для более старой версии библиотеки поддержки
источник
Предполагая,
mItems
что это коллекция, которая поддерживает вашAdapter
, почему вы удаляете все и снова добавляете? Вы в основном говорите ему, что все изменилось, поэтому RecyclerView повторно связывает все представления, чем я предполагаю, библиотека изображений не обрабатывает его должным образом, когда он по-прежнему сбрасывает представление, даже если это тот же URL-адрес изображения. Возможно, у них было какое-то запеченное решение для AdapterView, чтобы оно отлично работало в GridView.Вместо вызова,
notifyDataSetChanged
который вызовет повторную привязку всех представлений, вызовите подробные события уведомления (уведомление о добавлении / удалении / перемещении / обновлении), чтобы RecyclerView повторно связывал только необходимые представления и ничего не мерцало.источник
Recyclerview использует DefaultItemAnimator в качестве аниматора по умолчанию. Как видно из приведенного ниже кода, они меняют альфа-канал держателя представления при изменении элемента:
Я хотел сохранить остальную анимацию, но убрать «мерцание», поэтому я клонировал DefaultItemAnimator и удалил 3 альфа-строки выше.
Чтобы использовать новый аниматор, просто вызовите setItemAnimator () в своем RecyclerView:
источник
В Kotlin вы можете использовать расширение класса для RecyclerView:
источник
Привет, @Ali, возможно, уже поздно. Я также столкнулся с этой проблемой и решил с помощью решения ниже, это может помочь вам, пожалуйста, проверьте.
Класс LruBitmapCache.java создан для получения размера кеша изображений
Одноэлементный класс VolleyClient.java [расширяет приложение], добавленный под кодом
в конструкторе одноэлементного класса VolleyClient добавьте ниже фрагмент для инициализации ImageLoader
Я создал метод getLruBitmapCache () для возврата LruBitmapCache
Надеюсь, это поможет вам.
источник
для меня
recyclerView.setHasFixedSize(true);
работалисточник
В моем случае ни одно из вышеперечисленных, ни ответы на другие вопросы о стеке с такими же проблемами не помогли.
Ну, я использовал настраиваемую анимацию каждый раз, когда щелкали элемент, для чего я вызывал notifyItemChanged (int position, Object Payload), чтобы передать полезные данные моему классу CustomAnimator.
Обратите внимание, что в адаптере RecyclerView доступно 2 метода onBindViewHolder (...). Метод onBindViewHolder (...) с тремя параметрами всегда будет вызываться перед методом onBindViewHolder (...) с двумя параметрами.
Как правило, мы всегда переопределяем метод onBindViewHolder (...), имеющий 2 параметра, и основная причина проблемы заключалась в том, что я делал то же самое, поскольку каждый раз, когда вызывается notifyItemChanged (...), наш метод onBindViewHolder (...) будет быть вызванным, в котором я загружал свое изображение в ImageView с помощью Picasso, и это было причиной его повторной загрузки, независимо от того, из памяти или из Интернета. До загрузки он показывал мне изображение заполнителя, которое было причиной мигания в течение 1 секунды, когда я нажимаю на просмотр элемента.
Позже я также переопределил другой метод onBindViewHolder (...), имеющий 3 параметра. Здесь я проверяю, пуст ли список полезных нагрузок, затем я возвращаю реализацию суперкласса этого метода, иначе, если есть полезные нагрузки, я просто устанавливаю альфа-значение itemView держателя на 1.
И, к сожалению, я получил решение своей проблемы, потратив на это целый день!
Вот мой код для методов onBindViewHolder (...):
onBindViewHolder (...) с двумя параметрами:
onBindViewHolder (...) с 3 параметрами:
Вот код метода, который я вызывал в onClickListener объекта viewHolder itemView в onCreateViewHolder (...):
Примечание. Вы можете получить эту позицию, вызвав метод getAdapterPosition () вашего viewHolder из onCreateViewHolder (...).
Я также переопределил метод getItemId (int position) следующим образом:
и позвонил
setHasStableIds(true);
мой объект адаптера в действии.Надеюсь, это поможет, если ни один из приведенных выше ответов не работает!
источник
В моем случае была гораздо более простая проблема, но она может выглядеть / ощущаться очень похоже на проблему выше. Я преобразовал ExpandableListView в RecylerView с помощью Groupie (используя функцию Groupie ExpandableGroup). В моем первоначальном макете был такой раздел:
Если для layout_height установлено значение «wrap_content», анимация из расширенной группы в свернутую выглядела так, как будто она будет мигать, но на самом деле это просто анимация из «неправильной» позиции (даже после того, как вы попробовали большинство рекомендаций в этом потоке).
В любом случае, простое изменение layout_height на match_parent решило проблему.
источник
У меня была аналогичная проблема, и это сработало для меня. Вы можете вызвать этот метод, чтобы установить размер кеша изображений.
источник
для моего приложения у меня были некоторые изменения данных, но я не хотел, чтобы весь вид мигал.
Я решил это, только уменьшив альфа-канал oldview до 0,5 и начав альфа-канал newview с 0,5. Это создало более мягкий переход затухания без полного исчезновения изображения.
К сожалению, из-за частных реализаций я не смог создать подкласс DefaultItemAnimator, чтобы внести это изменение, поэтому мне пришлось клонировать код и внести следующие изменения
в animateChange:
в animateChangeImpl:
источник
Использование соответствующих методов recyclerview для обновления представлений решит эту проблему.
Сначала внесите изменения в список
Затем сообщите, используя
Надеюсь, это поможет !!
источник
Попробуйте использовать stableId в режиме ресайклера. В следующей статье это кратко объясняется.
https://medium.com/@hanru.yeh/recyclerviews-views-are-blinking-when-notifydatasetchanged-c7b76d5149a2
источник
Котлинское решение:
источник