android - 在notifyDatasetChanged()之后,RecyclerView闪烁

我有一个RecyclerView,它从API加载一些数据,包括一个图像URL和一些数据,我使用networkImageView来延迟加载图像。

@Override

public void onResponse(List 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,它按预期工作。 没有瞎眼。

onViewCreated of my Fragment中的RecycleView配置:

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);

有人遇到过这样的问题吗? 可能是什么原因?

13个解决方案

97 votes

尝试在RecyclerView.Adapter中使用稳定的ID

notifyDataSetChanged()并覆盖getItemId(int position)。

没有稳定的ID,在notifyDataSetChanged()之后,ViewHolders通常被分配到不同的位置。 这就是我案件中闪烁的原因。

你可以在这里找到一个很好的解释。

Anatoly Vdovichev answered 2019-09-02T00:14:50Z

85 votes

根据这个问题页面....它是默认的recycleview项目更改动画...你可以关闭它..试试这个

recyclerView.getItemAnimator().setSupportsChangeAnimations(false);

更新最新版本

引自Android开发人员博客:

请注意,此新API不向后兼容。 如果你以前   实现了ItemAnimator,你可以改为扩展   SimpleItemAnimator,它通过包装新的API来提供旧的API  API。 您还会注意到某些方法已被完全删除   来自ItemAnimator。 例如,如果你打电话  recyclerView.getItemAnimator()。setSupportsChangeAnimations(假),   此代码将不再编译。 您可以将其替换为:

ItemAnimator animator = recyclerView.getItemAnimator();

if (animator instanceof SimpleItemAnimator) {

((SimpleItemAnimator) animator).setSupportsChangeAnimations(false);

}

Sabeer Mohammed answered 2019-09-02T00:15:39Z

34 votes

这简单有效:

recyclerView.getItemAnimator().setChangeDuration(0);

Hamzeh Soboh answered 2019-09-02T00:16:03Z

8 votes

我有一些问题从一些网址加载图像,然后imageView闪烁。通过使用解决

notifyItemRangeInserted()

代替

notifyDataSetChanged()

这避免了重新加载那些未更改的旧数据。

Wesely answered 2019-09-02T00:16:40Z

7 votes

尝试此操作以禁用默认动画

ItemAnimator animator = recyclerView.getItemAnimator();

if (animator instanceof SimpleItemAnimator) {

((SimpleItemAnimator) animator).setSupportsChangeAnimations(false);

}

这是自Android支持23以来禁用动画的新方法

这种旧方法适用于旧版本的支持库

recyclerView.getItemAnimator().setSupportsChangeAnimations(false)

Mohamed Farouk answered 2019-09-02T00:17:17Z

2 votes

假设notifyDataSetChanged是支持Adapter的集合,为什么要删除所有内容并重新添加? 你基本上告诉它一切都已经改变,所以RecyclerView重新绑定所有视图,而不是我假设图像库没有正确处理它仍然重置视图,即使它是相同的图像URL。 也许他们在AdapterView的解决方案中有一些很好用,所以它在GridView中运行良好。

调用粒度通知事件(通知已添加/删除/移动/更新),而不是调用将导致重新绑定所有视图的notifyDataSetChanged,以便RecyclerView将仅重新绑定必要的视图,并且不会闪烁任何内容。

yigit answered 2019-09-02T00:17:49Z

2 votes

Recyclerview使用DefaultItemAnimator作为默认动画师。从下面的代码中可以看出,它们会在项目更改时更改视图持有者的alpha:

@Override

public boolean animateChange(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder, int fromX, int fromY, int toX, int toY) {

...

final float prevAlpha = ViewCompat.getAlpha(oldHolder.itemView);

...

ViewCompat.setAlpha(oldHolder.itemView, prevAlpha);

if (newHolder != null) {

....

ViewCompat.setAlpha(newHolder.itemView, 0);

}

...

return true;

}

我想保留其余的动画,但删除“闪烁”,所以我克隆了DefaultItemAnimator并删除了上面的3个alpha行。

要使用新的动画师,只需在您的RecyclerView上调用setItemAnimator():

mRecyclerView.setItemAnimator(new MyItemAnimator());

Peter File answered 2019-09-02T00:18:26Z

1 votes

嘿@Ali可能是迟到的回复。 我也遇到了这个问题并通过以下解决方案解决,它可以帮助您检查。

创建LruBitmapCache.java类以获取图像缓存大小

import android.graphics.Bitmap;

import android.support.v4.util.LruCache;

import com.android.volley.toolbox.ImageLoader.ImageCache;

public class LruBitmapCache extends LruCache implements

ImageCache {

public static int getDefaultLruCacheSize() {

final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);

final int cacheSize = maxMemory / 8;

return cacheSize;

}

public LruBitmapCache() {

this(getDefaultLruCacheSize());

}

public LruBitmapCache(int sizeInKiloBytes) {

super(sizeInKiloBytes);

}

@Override

protected int sizeOf(String key, Bitmap value) {

return value.getRowBytes() * value.getHeight() / 1024;

}

@Override

public Bitmap getBitmap(String url) {

return get(url);

}

@Override

public void putBitmap(String url, Bitmap bitmap) {

put(url, bitmap);

}

}

VolleyClient.java单例类[extends Application]在代码下面添加了

在VolleyClient单例类构造函数中添加下面的代码片段来初始化ImageLoader

private VolleyClient(Context context)

{

mCtx = context;

mRequestQueue = getRequestQueue();

mImageLoader = new ImageLoader(mRequestQueue,getLruBitmapCache());

}

我创建了getLruBitmapCache()方法来返回LruBitmapCache

public LruBitmapCache getLruBitmapCache() {

if (mLruBitmapCache == null)

mLruBitmapCache = new LruBitmapCache();

return this.mLruBitmapCache;

}

希望它会帮助你。

Android learner answered 2019-09-02T00:19:22Z

0 votes

我有类似的问题,这对我有用您可以调用此方法来设置图像缓存的大小

private int getCacheSize(Context context) {

final DisplayMetrics displayMetrics = context.getResources().

getDisplayMetrics();

final int screenWidth = displayMetrics.widthPixels;

final int screenHeight = displayMetrics.heightPixels;

// 4 bytes per pixel

final int screenBytes = screenWidth * screenHeight * 4;

return screenBytes * 3;

}

developer_android answered 2019-09-02T00:19:47Z

0 votes

对于我的应用程序,我有一些数据更改但我不希望整个视图闪烁。

我解决了它只是将旧视图淡化0.5 alpha并开始新视图alpha为0.5。 这样可以创建更柔和的渐变过渡,而不会使视图完全消失。

不幸的是,由于私有实现,我无法继承DefaultItemAnimator以进行此更改,因此我不得不克隆代码并进行以下更改

在animateChange中:

ViewCompat.setAlpha(newHolder.itemView, 0); //change 0 to 0.5f

在animateChangeImpl中:

oldViewAnim.alpha(0).setListener(new VpaListenerAdapter() { //change 0 to 0.5f

Deefer answered 2019-09-02T00:20:37Z

0 votes

对我来说recyclerView.setHasFixedSize(true);工作

Pramod answered 2019-09-02T00:21:01Z

0 votes

使用适当的recyclerview方法更新视图将解决此问题

首先,在列表中进行更改

mList.add(item);

or mList.addAll(itemList);

or mList.remove(index);

然后通知使用

notifyItemInserted(addedItemIndex);

or

notifyItemRemoved(removedItemIndex);

or

notifyItemRangeChanged(fromIndex, newUpdatedItemCount);

希望这会有所帮助!!

Sreedhu Madhu answered 2019-09-02T00:21:44Z

0 votes

尝试在recycler视图中使用stableId。 以下文章简要解释了它

[https://medium.com/@hanru.yeh/recyclerviews-views-are-blinking-when-notifydatasetchanged-c7b76d5149a2]

Farruh Habibullaev answered 2019-09-02T00:22:16Z

android addview 闪屏,android - 在notifyDatasetChanged()之后,RecyclerView闪烁相关推荐

  1. android 9闪屏,android 9图片制作 显示会出现闪屏怎么处理

    0X000000该内存不能为read的解决方法0X000000该内存不能为read的解决方法 运行某些程序的时候,有时会出现内存错误的提示,然后该程序就关闭. "0x????????&quo ...

  2. Android Splash闪屏页秒开 Activity白屏、Activity黑屏问题

    本文转自严振杰的博客: http://blog.csdn.net/yanzhenjie1003 今天在处理项目中闪屏界面的时候,遇到程序第一次开启会出现白屏大约2秒左右,然后再执行闪屏,故找到该篇文章 ...

  3. 设置android应用闪屏图片_Android实现启动页面(闪屏页面)

    不难发现,我们手机上的很多app都有启动页面,例如打开简书App在显示主页文章前会有一个启动页面,如下所示: 简书启动页面 随后是一个广告页面,最后才进入到主页去. 那么我们自己怎么实现这个效果呢?下 ...

  4. android webview加载闪屏,Android Webview:加载url时出现闪屏

    我是Android应用程序中的新手,这是我的第一个应用程序. 我已经创建了启动画面和工程..但其后走了一个长长的白色空白屏幕约2-5秒,然后URL开始加载..Android Webview:加载url ...

  5. android 微信绑定闪屏,Android微信登录后黑屏闪屏问题

    本文链接:http://blog..net/dreamsever/article/details/53118864 最近项目要加一个微信登录的功能,由于以前其他项目使用过微信登录,而且该在的东西都在, ...

  6. Android 简单闪屏

    参考 http://www.cnblogs.com/royenhome/archive/2010/05/05/1727971.html MainMenu.java package com.demo; ...

  7. Android 9闪屏页面适配问题

    闲谈 距离上一篇博客已经两个月的时间了,一是年底的工作任务确实加重了一些,二是自己也有些懈怠了--让自己写博客的时间为其他事情让步.好在昨天任务完成,今天放松的休息了一上午,觉得还是要做点什么,来庆祝 ...

  8. android glsurface 闪屏,在null对象引用上的android.opengl.GLSurfaceView $GLThread.surfaceCreated()’...

    我试图使用GLSurface来显示自定义视图. 我的xml xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:to ...

  9. android addview指定位置,Android开发中,请问当在一个视图中addView另一个布局视图时为什么报错?...

    Android开发中,我在一个视图中addView另一个布局视图(该视图通过inflate加载获得,其中root为null即没有附加parent视图),为什么还是会报错误: The specified ...

最新文章

  1. extjs grid renderer用法
  2. java 反序列化漏洞简介
  3. 【数据挖掘】关联规则挖掘 Apriori 算法 ( 关联规则简介 | 数据集 与 事物 Transaction 概念 | 项 Item 概念 | 项集 Item Set | 频繁项集 | 示例解析 )
  4. javascript对象操作总结
  5. 今晚八点 | 追问研讨会:我们如何建立更好的精神疾病模型?
  6. mariadb集群初次启动方法
  7. 64位系统安装ODBC驱动的方法
  8. Android_项目文件结构目录分析
  9. python万年历_python万年历
  10. iis6扩展php_windows2003server中iis6多版本php配置方法
  11. Java面向对象--instanceof关键字
  12. java多分支流程图_Java 流程控制 之 分支结构(条件判断)
  13. 前端leader找我谈心:我是如何从刚毕业的前端菜鸟一步步成长为前端工程师的?...
  14. DeFi之道丨告别朝九晚五,一文了解区块链新组织形式DO
  15. Silicon单片机芯片解密
  16. 杂记二 · 永远不服输
  17. vue饿了么项目实现评论列表的筛选
  18. 简书收入结算与提现常见问题
  19. Centos7 配置163邮箱
  20. 我的试题回顾(16-18)

热门文章

  1. 娱乐视频直播为什么需要DASH
  2. CentOS 7 搭建ntp时钟服务器
  3. 雷达 固件 调试_本周我们的雷达:Google,浏览器中的构建工具和调试
  4. 学习笔记第五十节:原根相关与二次剩余
  5. PBD加密,PBD加密专家
  6. 数据分析之numpy实例
  7. 那些年被HR虐过的面试题,你是怎么回答的
  8. 谷歌又开始放飞自我了...
  9. 电路理论基础学习笔记(2):chap1 电路元件与电路基本定律
  10. W801 W800 W806串口下载失败的原因