RecyclerView不同item顯示及性能優(yōu)化

下面內(nèi)容是以水平方向上的LinearLayoutManager作為演示

AbstractHolder.java 抽象Adapter, 主要是為了避免在onBindViewHolder中做太多事情,內(nèi)容如下:

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

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

不同item元素的樣式不同是通過(guò)getItemViewType來(lái)確定,默認(rèn)為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) {
        //根據(jù)對(duì)象獲取具體的元素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);
        // 處理一些資源回收的事情
    }

常用的性能優(yōu)化

// 提前占坑,默認(rèn)為2
LinearLayoutManager lm = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false);
        lm.setInitialPrefetchItemCount(5);

// 設(shè)置緩存
rvDevices.setItemViewCacheSize(200);
// 設(shè)置部分或固定的尺寸
rvDevices.setHasFixedSize(true);
// 滾動(dòng)事件派發(fā)
rvDevices.setNestedScrollingEnabled(false);

// ConstrainLayout作為根布局元素,避免過(guò)分嵌套.

RecyclerView仿ViewPager的左右滑動(dòng)切換

        int offsetX; // 滑動(dòng)偏移,確保下一個(gè)頁(yè)面的位置
        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時(shí)根據(jù)偏移切換索引.
        recyclerview.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_UP:
                        //滑動(dòng)距離超過(guò)recycleview的0.2倍寬度時(shí)換頁(yè)
                        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延遲加載

避免頁(yè)面內(nèi)item/viewType過(guò)多卡頓問(wèn)題,延遲UI加載時(shí)機(jī)至滑動(dòng)停止后再加載可見的holder.
Note:需提前給默認(rèn)的頁(yè)面元素設(shè)置UI占位內(nèi)容,避免一片灰白??蓞⒖糶ithub上的空白占位. 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: //列表靜止時(shí)才加載UI及綁定事件,以解決列表滑動(dòng)時(shí)卡頓的問(wèn)題
                        deviceAdapter.setCanInitView(true);
                        deviceAdapter.notifyDataSetChanged();
                        break;
                    case RecyclerView.SCROLL_STATE_DRAGGING: //正在用手指拖動(dòng)
                    case RecyclerView.SCROLL_STATE_SETTLING: //松手后的慣性滾動(dòng)
                        deviceAdapter.setCanInitView(false);
                        break;                }
            }

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容