美文网首页
RecyclerView不同item显示及性能优化

RecyclerView不同item显示及性能优化

作者: 钰大人 | 来源:发表于2018-09-30 15:58 被阅读0次

下面内容是以水平方向上的LinearLayoutManager作为演示

AbstractHolder.java 抽象Adapter, 主要是为了避免在onBindViewHolder中做太多事情,内容如下:

    public AbstractHolder(View itemView) {
        super(itemView);
    }

    public abstract void onBind(XXX mo);
    public abstract void updateUI(XXX mo);
    public abstract void onUnBind();

不同item元素的样式不同是通过getItemViewType来确定,默认为0。具体Adapter如下,仅展示具体代码.

    @NonNull
    @Override
    public AbstractHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        AbstractHolder holder = null;
        View v;
        switch (viewType) {
            case MOUtils.DEV_ViewType_0:
                break;
            case MOUtils.DEV_ViewType_1:
                break;
            case MOUtils.DEV_ViewType_2:
                break;
            case MOUtils.DEV_ViewType_3:
                break;
            case MOUtils.DEV_ViewType_4:
                break;
        }
        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull AbstractHolder holder, int position) {
        MOBase mo = mMOList.get(position);
        holder.onBind(mo);
    }

    @Override
    public int getItemCount() {
        return mMOList.size();
    }

    @Override
    public long getItemId(int position) {
        return mSoleID.getAndIncrement();
    }

    @Override
    public int getItemViewType(int position) {
        //根据对象获取具体的元素style.
        MOBase mo = mMOList.get(position);
        return MOUtils.getMOViewType(mo);
    }

    @Override
    public void onViewRecycled(@NonNull AbstractHolder holder) {
        super.onViewRecycled(holder);
        // 处理一些资源回收的事情
    }

    @Override
    public void onViewDetachedFromWindow(@NonNull AbstractHolder holder) {
        super.onViewDetachedFromWindow(holder);
        // 处理一些资源回收的事情
    }

常用的性能优化

// 提前占坑,默认为2
LinearLayoutManager lm = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false);
        lm.setInitialPrefetchItemCount(5);

// 设置缓存
rvDevices.setItemViewCacheSize(200);
// 设置部分或固定的尺寸
rvDevices.setHasFixedSize(true);
// 滚动事件派发
rvDevices.setNestedScrollingEnabled(false);

// ConstrainLayout作为根布局元素,避免过分嵌套.

RecyclerView仿ViewPager的左右滑动切换

        int offsetX; // 滑动偏移,确保下一个页面的位置
        recyclerview.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                offsetX = 0;
                super.onScrollStateChanged(recyclerView, newState);
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                offsetX += dx;
                super.onScrolled(recyclerView, dx, dy);
            }
        });

        // UP时根据偏移切换索引.
        recyclerview.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_UP:
                        //滑动距离超过recycleview的0.2倍宽度时换页
                        if (offsetX <= -mRcContainer.getWidth() * 0.2) {
                            currIndex -= 1;
                            currIndex = (currIndex < 0) ? 0: currIndex;
                        } else if (offsetX >= mRcContainer.getWidth() * 0.2) {
                            currIndex += 1;
                            currIndex = currIndex > adapter.getItemCount() ? adapter.getItemCount()-1 : currIndex;
                        }

                        mRcContainer.smoothScrollToPosition(currIndex);
                        return true;
                }
                return false;
            }
        });

UI延迟加载

避免页面内item/viewType过多卡顿问题,延迟UI加载时机至滑动停止后再加载可见的holder.
Note:需提前给默认的页面元素设置UI占位内容,避免一片灰白。可参考github上的空白占位. https://github.com/sharish/ShimmerRecyclerView

    //Adapter onBind
    @Override
    public void onBindViewHolder(@NonNull AbstractHolder holder, int position) {
        if (canInitView) {
            MOBase mo = mMOList.get(position);
            holder.onBind(mo);
        }
    }


     // recyclerview
     rvDevices.addOnScrollListener(new RecyclerView.OnScrollListener() {
         @Override
         public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
             super.onScrollStateChanged(recyclerView, newState);

             switch (newState) {
                    case RecyclerView.SCROLL_STATE_IDLE: //列表静止时才加载UI及绑定事件,以解决列表滑动时卡顿的问题
                        deviceAdapter.setCanInitView(true);
                        deviceAdapter.notifyDataSetChanged();
                        break;
                    case RecyclerView.SCROLL_STATE_DRAGGING: //正在用手指拖动
                    case RecyclerView.SCROLL_STATE_SETTLING: //松手后的惯性滚动
                        deviceAdapter.setCanInitView(false);
                        break;                }
            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
            }
        });

相关文章

网友评论

      本文标题:RecyclerView不同item显示及性能优化

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