1. 程式人生 > >讓多種型別item的Recyclerview能夠上拉和下拉重新整理--XRefreshView

讓多種型別item的Recyclerview能夠上拉和下拉重新整理--XRefreshView

什麼是XRefreshView

XRefreshView是一款支援任何view上拉載入和下拉重新整理的庫,之所以說是任何view,是因為他不僅在內部適配了Recyclerview,abslistview,scrollview,webview等view,還提供了讓你自己去判斷view到達頂部和底部的方法,就像這樣,

    refreshView.setOnTopRefreshTime(new OnTopRefreshTime() {  

                @Override  
                public boolean isTop() {  
                    return
stickyLv.getFirstVisiblePosition() == 0; } }); refreshView.setOnBottomLoadMoreTime(new OnBottomLoadMoreTime() { @Override public boolean isBottom() { return stickyLv.getLastVisiblePosition() == mTotalItemCount - 1
; } });

當isTop返回true,就會觸發下拉重新整理;當isBottom()返回true,就會觸發上拉載入。此外還能自己定義重新整理的頭部和載入的底部,具體的用法可以參考github上給的demo和我之前寫的部落格。我會在文章末尾處貼出來。

支援多種型別的item

背景

前段時間有不少朋友都問我用XRefreshView重新整理Recyclerview的時候,Recyclerview怎麼支援多種型別的item,其實XRefreshView很早就支援這個功能了,但是很多人可能並不清楚怎麼支援,所以我感覺有必要單獨寫篇部落格來說明下這個問題。

效果圖

效果圖
能看到效果圖上Recyclerview有文字在左邊和文字在右邊這兩種佈局。demo寫的比較簡陋,但是也能解決問題。接下來看具體操作。

步驟

RecyclerView的adapter得繼承BaseRecyclerAdapter

public class MultiItemAdapter extends BaseRecyclerAdapter<MultiItemAdapter.SimpleAdapterViewHolder> {

    /**
     * 替代onBindViewHolder方法,實現這個方法就行了
     */
    @Override
    public void onBindViewHolder(SimpleAdapterViewHolder holder, int position, boolean isItem) {
         Person person = list.get(position);
        int type = getAdapterItemViewType(position);
        if (type == 0) {
            holder.tvLeft.setText(person.getName());
        } else {
            holder.tvRight.setText(person.getName());
        }
    }

    /**
     * 實現此方法來設定viewType
     */
    @Override
    public int getAdapterItemViewType(int position) {
        if (list != null && list.size() > 0) {
            return list.get(position).getType();
        }
        return 0;
    }

    /**
     * 設定Recyclerview上資料的數量,代替getAdapterCount()
     */
    @Override
    public int getAdapterItemCount() {
        return list.size();
    }

    /**
     * 用來設定headerview和footerview的viewholder的,只需要返回一個viewholder,這麼寫就行了
     */
    @Override
    public SimpleAdapterViewHolder getViewHolder(View view) {
        return new SimpleAdapterViewHolder(view, false);
    }

    public void setData(List<Person> list) {
        this.list = list;
        notifyDataSetChanged();
    }

    /**
     * 替代onBindViewHolder方法,實現這個方法就行了
     */
    @Override
    public SimpleAdapterViewHolder onCreateViewHolder(ViewGroup parent, int viewType, boolean isItem) {
        View v = null;
        if (viewType == 0) {
            v = LayoutInflater.from(parent.getContext()).inflate(
                    R.layout.item_left_recylerview, parent, false);
        } else {
            v = LayoutInflater.from(parent.getContext()).inflate(
                    R.layout.item_right_recylerview, parent, false);
        }
        return new SimpleAdapterViewHolder(v, viewType, true);
    }

    public class SimpleAdapterViewHolder extends RecyclerView.ViewHolder {

         public TextView tvRight, tvLeft;

        public SimpleAdapterViewHolder(View itemView, boolean isItem) {
            super(itemView);
            init(itemView, -1, isItem);
        }

        public SimpleAdapterViewHolder(View itemView, int viewType, boolean isItem) {
            super(itemView);
            init(itemView, viewType, isItem);
        }

        private void init(View itemView, int viewType, boolean isItem) {
            if (isItem) {
                switch (viewType) {
                    case 0:
                        tvLeft= (TextView) itemView.findViewById(R.id.tv_multi_left);
                        break;
                    default:
                        tvRight= (TextView) itemView.findViewById(R.id.tv_multi_right);
                        break;
                }
            }
        }
    }

  ...省略部分程式碼...

}
  1. 先通過getAdapterItemViewType()來設定item的viewtype,設定好viewtype以後,接下來就是使用這個viewtype了;
  2. 在onCreateViewHolder(ViewGroup parent, int viewType, boolean isItem)里根據viewtype建立不同佈局的viewholder,並給根據viewtype給viewholder中的控制元件賦值;
  3. 最後在onBindViewHolder()中根據viewtype給不同的控制元件設定ui。

不過有點是需要注意的,BaseRecyclerAdapter的headerview和footerview也是有viewtype,所以在考慮viewtype值的時候,不能和headerview和footerview的viewtype衝突。

  protected class VIEW_TYPES {
        public static final int FOOTER = -1;
        public static final int HEADER = -3;
        public static final int NORMAL = -4;
    }

上面就是BaseRecyclerAdapter用到的viewtype的值,注意下就行了。

其實還有很多特性,例如Recyclerview上拉載入結束以後不隱藏footerview,或者資料載入完成以後footerview顯示 沒有更多內容,考慮下篇部落格再介紹吧。其實這些特性在github上的demo裡都有寫到,看看程式碼就能找到,如果有使用上的問題,歡迎來github上找到我。

相關部落格:

github

預告

懸浮球
下篇部落格是關於懸浮球的,相較於網上大多數懸浮球來說,這個懸浮球最大優點是不需要許可權,具體的會在部落格裡說明。程式碼已經在github上了,點我獲取原始碼,有需要可以先看看。