給RecyclerView新增showLoadng、showEmpty、showError和LoadMore功能

月光邊境發表於2018-01-19

通常來說載入一個列表的資料會有以下幾種狀態:載入中、載入失敗,資料列表為空,正常的資料列表以及載入更多。 在以前使用ListView的時候可以通過setEmptyView來設定空佈局,但是RecyclerView沒有這樣自帶的方法。 所以我通過自己實現一個RecyclerView.Adapter來統一處理這幾種狀態,然後專案裡面給RecyclerView設定 Adapter的時候都繼承該StatusAdapter。

效果圖:

demo.gif

支援功能

  • 很方便的新增LoadngView、EmptyView、ErrorView
  • 滑動到底部自動載入更多
  • 資料列表為空時自動顯示EmptyView
  • 支援給EmptyView、ErrorView設定點選事件監聽
  • 狀態View懶載入
  • 自定義UI,自定義Empty、Error狀態的bindView操作

Github地址 (https://github.com/wangyiwy/StatusAdapter)

使用方法

  • 繼承StatusAdapter
  • 實現onCreateDataViewHolder onBindDataViewHolder getDataItemCount
  • 如果需要實現多種佈局,使用getDataItemType代替以前的getItemType
  • 改變狀態:mAdapter.showLoading() mAdapter.showEmpty() mAdapter.showError() mAdapter.showNormal(),如果當前是STATUS_NORMAL狀態當資料被清空的時候會自動顯示EmptyView
  • 新增載入更多監聽 並在載入結束呼叫onLoadingFinish方法。 舉個栗子:
  1. 繼承StatusAdapter
    private class MyAdapter extends StatusAdapter<RecyclerView.ViewHolder> {
        private final int VIEW_TYPE_TEXT = 1;
        private final int VIEW_TYPE_IMAGE = 2;

        private List<String> mDataList;

        public MyAdapter(List<String> dataList) {
            this.mDataList = dataList;
        }

        @Override
        public RecyclerView.ViewHolder onCreateDataViewHolder(ViewGroup parent, int viewType) {
            if (viewType == VIEW_TYPE_TEXT) {
                View itemView = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.item_list_text, parent, false);
                return new TextDataHolder(itemView);
            } else {
                View itemView = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.item_list_image, parent, false);
                return new ImageDataHolder(itemView);
            }
        }

        @Override
        public void onBindDataViewHolder(RecyclerView.ViewHolder holder, int position) {
            if (holder instanceof TextDataHolder) {
                TextDataHolder textDataHolder = (TextDataHolder) holder;
                textDataHolder.textView.setText("Hello World! " + position);
            } else if (holder instanceof ImageDataHolder) {
                //todo bindImageDataViewHolder
            }
        }

        @Override
        public int getDataItemCount() {
            return mDataList.size();
        }

        @Override
        public int getDataItemType(int position) {
            if (position % 2 == 0) {
                return VIEW_TYPE_TEXT;
            } else {
                return VIEW_TYPE_IMAGE;
            }
        }

        @Override
        protected void bindEmptyViewHolder(RecyclerView.ViewHolder holder) {
            super.bindEmptyViewHolder(holder);
            //可以在這裡實現自定義操作
        }

        @Override
        protected void bindErrorViewHolder(RecyclerView.ViewHolder holder) {
            super.bindErrorViewHolder(holder);
            //可以在這裡實現自定義操作
        }

        @Override
        protected int getLoadingLayout() {
            //重寫此方法或者createLoadingViewHolder方法修改LoadingView
            return super.getLoadingLayout();
        }

        @Override
        protected int getEmptyLayout() {
            //重寫此方法或者createEmptyViewHolder方法修改EmptyView
            return super.getEmptyLayout();
        }

        @Override
        protected int getErrorLayout() {
            //重寫此方法或者createErrorViewHolder方法修改ErrorView
            return super.getErrorLayout();
        }

        @Override
        protected int getLoadMoreLayout() {
            //重寫此方法或者createLoadMoreHolder方法修改ErrorView
            return super.getLoadMoreLayout();
        }
    }
複製程式碼
  1. 使用Adapter
        //新增點選事件
        mAdapter.setOnStatusViewClickListener(new OnStatusViewClickListener() {
            @Override
            public void onEmptyViewClick(View view) {
                Toast.makeText(view.getContext(), "OnEmptyViewClick",
                        Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onErrorViewClick(View view) {
                Toast.makeText(view.getContext(), "OnErrorViewClick",
                        Toast.LENGTH_SHORT).show();
            }
        });
複製程式碼
        //載入更多監聽
        mAdapter.setOnLoadMoreListener(new OnLoadMoreListener() {
            @Override
            public void onLoadMore() {
                //... 載入下一頁資料
            }
        });
複製程式碼
       //載入完成
       mAdapter.onLoadingFinish();
複製程式碼

相關文章