RecyclerView滚动性能 [英] RecyclerView Scrolling Performance

查看:138
本文介绍了RecyclerView滚动性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已根据创建列表和卡片指南创建了RecyclerView示例。我的适配器只有一个模式实现来扩展布局。

I have created RecyclerView example basing on Creating Lists and Cards guide. My adapter have a pattern implementation only for inflate the layout.

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

The problem is the poor scrolling performance. This in a RecycleView with only 8 items.

在某些测试中,我确认在Android L中没有出现此问题。但在KitKat版本中,性能的下降是显而易见的。

In some tests I verified that in Android L this problem does not occurs. But in the KitKat version the decreasing of performance is evident.

推荐答案

我最近遇到了同样的问题,所以这就是我已经完成了最新的RecyclerView支持库:

I've recently faced the same issue, so this is what I've done with the latest RecyclerView support library:


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

  1. Replace a complex layout (nested views, RelativeLayout) with the new optimized ConstraintLayout. Activate it in Android Studio: Go to SDK Manager -> SDK Tools tab -> Support Repository -> check ConstraintLayout for Android & Solver for ConstraintLayout. Add to the dependencies:

compile 'com.android.support.constraint:constraint-layout:1.0.2'


  • 如果可能,请使用相同高度制作RecyclerView的所有元素。并添加:

  • If possible, make all elements of the RecyclerView with the same height. And add:

    recyclerView.setHasFixedSize(true);
    


  • 使用默认的RecyclerView 绘图缓存方法并根据它们进行调整对你的情况。您不需要第三方库来执行此操作:

  • Use the default RecyclerView drawing cache methods and tweak them according to your case. You don't need third party library to do so:

    recyclerView.setItemViewCacheSize(20);
    recyclerView.setDrawingCacheEnabled(true);
    recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
    


  • 如果你使用了很多图片,请确保他们的尺寸和压缩是最佳的。缩放图像也可能会影响性能。问题有两个方面 - 使用的源图像和解码的位图。以下示例为您提供了如何解码从Web下载的图像的提示:

  • If you use many images, make sure their size and compression are optimal. Scaling images may also affect the performance. There are two sides of the problem - the source image used and the decoded Bitmap. The following example gives you a hint how to decode аn image, downloaded from the web:

    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 - 它定义将为图像的每个像素使用多少字节。请注意,这是首选选项。如果源图像有更多颜色,它仍将使用不同的配置进行解码。

    The most important part is specifying inPreferredConfig - it defines how many bytes will be used for each pixel of the image. Keep in mind that this is a preferred option. If the source image has more colors, it will still be decoded with a different config.


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

    1. Make sure onBindViewHolder() is as cheap as possible. You can set OnClickListener once in onCreateViewHolder() and call through an interface a listener outside of the Adapter, passing the clicked item. This way you don't create extra objects all the time. Also check flags and states, before making any changes to the view here.

    viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View view) {
              Item item = getItem(getAdapterPosition());
              outsideClickListener.onItemClicked(item);
          }
    });
    


  • 当数据发生变化时,尝试仅更新受影响的项目。例如,不是使用 notifyDataSetChanged()使整个数据集无效,在添加/加载更多项目时,只需使用:

  • When data gets changed, try to update only the affected items. For example instead of invalidating the whole data set with notifyDataSetChanged(), when adding / loading more items, just use:

    adapter.notifyItemRangeInserted(rangeStart, rangeEnd);
    adapter.notifyItemRemoved(position);
    adapter.notifyItemChanged(position);
    adapter.notifyItemInserted(position);
    


  • 来自 Android开发者网站




    依靠notifyDataSetChanged()作为最后的手段。

    Rely on notifyDataSetChanged() as a last resort.

    但如果你需要要使用它,请使用唯一ID 维护您的商品:

    But if you need to use it, maintain your items with unique ids:

        adapter.setHasStableIds(true);
    




    RecyclerView将尝试合成可见的结构变化
    事件在使用此
    方法时报告它们具有稳定ID的适配器。这有助于动画和视觉
    对象持久性的目的但单个项目视图仍然需要
    反弹并重新输出。

    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仍然没有你想要的那么顺利。

    Even if you do everything right, chances are that the RecyclerView is still not performing as smoothly as you would like.

    这篇关于RecyclerView滚动性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆