美文网首页android开发知识点
[转]Android recycleView 的一些优化与相关问

[转]Android recycleView 的一些优化与相关问

作者: Thor_果冻 | 来源:发表于2018-12-29 15:31 被阅读199次

    转自:Android recycleView 的一些优化与相关问题

    recycleView 也出来很长时间了,记录一些自己见到的recycleView优化吧。

    1.recyclerView.setHasFixedSize(true);

    Item的高度是固定的,设置这个选项可以提高性能.总得来说就是就是避免整个布局绘制。就是避免requestLayout.

    具体的可以看看stackoverflow的这个几个问题

    Understanding RecyclerView setHasFixedSize

    When do we use the recyclerView.setHasFixedSize?

    设置这个可以避免重复的增删造成而外的浪费资源

    看完就差不多了

    2.复用RecycledViewPool

    总而言之
    如果RecycledView的adapter是一样的话可以考虑共享一个对象池。
    比如说:
    RecycledView嵌套RecycledView,里面的RecycledView大部分都adapter都一样。


    转自图片

    注意
    如果 LayoutManager是LinearLayoutManager或其子类(如GridLayoutManager)
    需要手动开启这个特性:layout.setRecycleChildrenOnDetach(true)

    例如:

    class OuterAdapter extends RecyclerView.Adapter<OuterAdapter.ViewHolder> {
        RecyclerView.RecycledViewPool mSharedPool = new RecyclerView.RecycledViewPool();
    
        ...
    
        @Override
    public void onCreateViewHolder(ViewGroup parent, int viewType) {
    
       RecyclerView view = new RecyclerView(inflater.getContext());
    
         LinearLayoutManager innerLLM = new LinearLayoutManager(parent.getContext(), LinearLayoutManager.HORIZONTAL);
            innerLLM.setRecycleChildrenOnDetach(true);
            innerRv.setLayoutManager(innerLLM);
            innerRv.setRecycledViewPool(mSharedPool);
            return new OuterAdapter.ViewHolder(innerRv);
        }
        ...
    

    3.横向嵌套RecyclerView滑动数据预加载,setInitialItemPrefetchCount

    注意只适合横向嵌套


    这里写图片描述

    在内部的 LayoutManager 中调用 LinearLayoutManager 的setInitialItemPrefetchCount()方法(25.1版本起可用)

    innerLLM.setInitialItemsPrefetchCount(num);

    num值看自己列表定把。不是越大越好。比如列表展示刚刚展示四个半item。就设置5.以此类推吧

    想了解具体的可以看看这篇文章
    RecyclerView 数据预取

    4.RecyclerView 预加载,getExtraLayoutSpace

    一开始我做这个漫画预览界面的时候就要用到提前加载图片。上面那个嵌套的不管用,这里要吐槽一下百度,-v-!mmp这搜索都是一样的答案!!!!!!.最后还是在stack overflow上才找到方案。

    只要增加预留的额外空间,就是改变滑动时预判的范围就可以了。

    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this) {
        @Override
        protected int getExtraLayoutSpace(RecyclerView.State state) {
            return 300;
        }
    };
    

    具体的可以看看这两个
    How to load all the images in the background of a RecyclerView in Android

    使用getExtraLayoutSpace为LayoutManager设置更多的预留空间

    5.特殊点的优化

    如果你觉得你的内存还ok,也就是要RecyclerViews有个流畅的体验。可以考虑设置下面的几点

    binding.fragmentCandidateBrowseList.setItemViewCacheSize(30);
    binding.fragmentCandidateBrowseList.setDrawingCacheEnabled(true);
    binding.fragmentCandidateBrowseList.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
    
    这里写图片描述

    来自于下面这篇文章,就是如何达到60fps。里面一些优化也可以看看
    RecyclerView Tips: How we achieved 60 FPS in Workable’s Android Recruiting App

    6.RecycleView与NestedScrollView的嵌套

    这是一个大坑,嵌套之后会发生一些奇奇怪怪的问题。

    • 比如莫名的在中间显示(焦点被抢)
    • RecycleView滑动会感觉到卡顿,可以通过mRecyclerView.setNestedScrollingEnabled(false);解决这个问题
    • 一次性加载所有item,而不是加载当前可见的Item,如果你的item布局够复杂或者条目很多,卡顿会很严重
    • 相关属性会失效,例如 linearManager.findLastVisibleItemPosition();获取当前第一个可见的position等…

    相关问题链接与对应的解决方案:

    3,和4.的话我是就没办法解决了,看了stackoverflow上的回答,就是最好别用嵌套。


    这里写图片描述

    7.RecycleView复杂布局相关建议

    刚刚上面有说道,尽量少用嵌套,可以避免很多不必要的坑。如果布局复杂呢?一定要用到嵌套呢?

    比如这个b站的这个直播布局


    这里写图片描述

    比较常见的布局上优化

    • 减少布局的嵌套,减少布局层次关系
    • <include>,<merge>,<ViewStub>等标签

    多类型,多布局
    按照平常的思维,编写上面的布局,一般情况是这样子的。

    这里写图片描述
    这样做是Ok的,但是随着业务的增长,东西都堆积在一个 Adapter,所以会变得繁琐,不好维护。

    我一般是通过这种多布局的方式去处理,把不用的业务分发到不同的viewHolder.

    所以我这边推荐我自认为还是ok的框架,小,且强大。

    —>>MultiType
    —>>Android 复杂的多类型列表视图新写法

    相关文章

      网友评论

        本文标题:[转]Android recycleView 的一些优化与相关问

        本文链接:https://www.haomeiwen.com/subject/imfplqtx.html