Android RecyclerView滚动性能 [英] Android RecyclerView Scrolling Performance

查看:65
本文介绍了Android 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.

问题在于滚动性能不佳.在只有8个项目的RecycleView中.

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. 用新的优化的ConstraintLayout替换复杂的布局(嵌套视图,RelativeLayout).在Android Studio中激活它:转到SDK Manager->"SDK工具"选项卡->支持存储库->选中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的所有元素的高度都相同.并添加:

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

  • 如果您使用许多图片,请确保其大小和压缩率是最佳的.缩放图像也可能会影响性能.问题有两个方面-使用的源图像和解码的位图.以下示例向您提示如何解码从网上下载的图像:

  • 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,然后通过接口调用Adapter外部的侦听器,并传递单击的项目.这样,您就不会一直创建额外的对象.在对视图进行任何更改之前,还请检查标志和状态.

    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.

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

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