java - Android RecyclerView 滚动性能

标签 java android performance android-recyclerview

我创建了基于 Creating Lists and Cards 的 RecyclerView 示例指导。我的适配器有一个仅用于扩展布局的模式实现。

问题是滚动性能不佳。这是在只有 8 个项目的 RecycleView 中。

在一些测试中,我验证了在 Android L 中不会出现这个问题。但是在 KitKat 版本中,性能下降是很明显的。

最佳答案

我最近遇到了同样的问题,所以这是我使用最新的 RecyclerView 支持库所做的:

  1. 用新优化的 ConstraintLayout 替换复杂的布局(嵌套 View ,RelativeLayout)。在 Android Studio 中激活它:转到 SDK Manager -> SDK Tools 选项卡 -> Support Repository -> 检查 ConstraintLayout for Android 和 Solver for ConstraintLayout。添加到依赖项:

    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    
  2. 如果可能,让 RecyclerView 的所有元素高度相同。并添加:

    recyclerView.setHasFixedSize(true);
    
  3. 使用默认的 RecyclerView 绘图缓存 方法并根据您的情况调整它们。您不需要第三方库即可:

    recyclerView.setItemViewCacheSize(20);
    recyclerView.setDrawingCacheEnabled(true);
    recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
    
  4. 如果您使用许多图片,请确保它们的尺寸和压缩效果最佳。缩放图像也可能会影响性能。问题有两个方面 - 使用的源图像和解码的位图。以下示例提示您如何解码从网络下载的图像:

    InputStream is = (InputStream) url.getContent();
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inPreferredConfig = Bitmap.Config.RGB_565;
    Bitmap image = BitmapFactory.decodeStream(is, null, options);
    

最重要的部分是指定 inPreferredConfig - 它定义了图像的每个像素将使用多少字节。请记住,这是一个首选选项。如果源图像有更多颜色,它仍然会使用不同的配置进行解码。

  1. 确保 onBindViewHolder() 尽可能便宜。您可以在 onCreateViewHolder() 中设置一次 OnClickListener 并通过接口(interface)调用适配器外部的监听器,传递单击的项目。这样您就不会一直创建额外的对象。在对此处的 View 进行任何更改之前,还要检查标志和状态。

    viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View view) {
              Item item = getItem(getAdapterPosition());
              outsideClickListener.onItemClicked(item);
          }
    });
    
  2. 当数据发生变化时,尝试仅更新受影响的项目。例如,在添加/加载更多项目时,不要使用 notifyDataSetChanged() 使整个数据集无效,只需使用:

    adapter.notifyItemRangeInserted(rangeStart, rangeEnd);
    adapter.notifyItemRemoved(position);
    adapter.notifyItemChanged(position);
    adapter.notifyItemInserted(position);
    
  3. 来自 Android Developer Web Site :

Rely on notifyDataSetChanged() as a last resort.

但如果您需要使用它,请使用唯一 ID 维护您的项目:

    adapter.setHasStableIds(true);

RecyclerView will attempt to synthesize visible structural change events for adapters that report that they have stable IDs when this method is used. This can help for the purposes of animation and visual object persistence but individual item views will still need to be rebound and relaid out.

即使您做对了所有事情,RecyclerView 仍有可能无法如您所愿顺利运行。

关于java - Android RecyclerView 滚动性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27188536/

相关文章:

java - Spring 属性(property)整合

java - 分割位图文件会产生 y + height 必须 <= bitmap.height() 错误

mysql - native MySQL 分区和基于后端的分区之间的性能差异?

javascript - Canvas :动画一个简单的星空

c# - 嵌套产量在树中的表现

java - 自定义 JavaFX 对话框

java - 打印存储在散列的散列中的元素

java - Kotlin:创建并引用真正的 Java 数组(用于 JNA)

android - 如何获取读取外部存储权限?

android - 如何将android中的高分辨率图像上传到.net API服务器?