RecyclerView 上拉加載的簡單封裝

先看效果:
這裏寫圖片描述

網上有很多這類得框架,不過在自己的項目只用到上拉加載的功能,所以自己封裝一個簡單點的。

主要依賴BaseRecyPRAdapter這個類,
首先要監聽recyclerview的滑動


/**
 * Package com.demo.view.recyclerview_pull_refresh.
 * Created by yaoh on 2017/08/21.
 * <p/>
 * Description:
 */
public abstract class BaseRecyPRAdapter<T> extends RecyclerView.Adapter<BaseRecyPRAdapter.BaseViewHolder> {
    private static final String TAG = "BaseRecyPRAdapter";

    public static final int VIEW_ITEM = 0;
    public static final int VIEW_PROG = 1;

    public List<T> mDataList;

    private final Context mContext;
    private final RecyclerView mRecyclerView;
    private int totalItemCount;
    private int lastVisibleItemPosition;
    boolean isShowFootVieW = false;
    private Handler handler = new Handler();

    private static final int STATE_NORMAL = 0;
    private static final int STATE_LOADING = 1;
    private static final int STATE_LOAD_COMPLETE = 2;
    private int mState = STATE_NORMAL;

    public BaseRecyPRAdapter(Context context, RecyclerView recyclerView) {
        mContext = context;
        mRecyclerView = recyclerView;
        if (mRecyclerView.getLayoutManager() instanceof LinearLayoutManager) {
            final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
            /**
             * 監聽recyclerview的滑動
             */
            mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                    super.onScrollStateChanged(recyclerView, newState);
                    int extent = recyclerView.computeVerticalScrollExtent();
                    int range = recyclerView.computeVerticalScrollRange();
                    Log.e(TAG, "\n extent = " + extent + "\n range = " + range);

                    /**
                     * 是否填充滿屏幕,沒有填充滿屏幕的情況下就不支持上拉加載更多了
                     */
                    if (range > extent) {
                        if(!isShowFootVieW){
                            notifyDataSetChanged();
                        }
                        isShowFootVieW = true;
                    } else {
                        isShowFootVieW = false;
                    }

                    totalItemCount = linearLayoutManager.getItemCount();
                    if (mState == STATE_NORMAL && newState == RecyclerView.SCROLL_STATE_IDLE &&
                            totalItemCount == lastVisibleItemPosition + 1 && range > extent) {
                        mState = STATE_LOADING;
                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                if (mLoadMoreDataListener != null) {
                                    mLoadMoreDataListener.loadMoreData();
                                }
                            }
                        });
                    }
                }

                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);
                    lastVisibleItemPosition = linearLayoutManager.findLastVisibleItemPosition();
                }
            });
        }

    }


    @Override
    public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        BaseViewHolder holder = null;
        View view = null;
        if (viewType == VIEW_PROG) {
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer, parent, false);
        } else {
            view = LayoutInflater.from(parent.getContext()).inflate(getLayoutId(viewType), parent, false);
        }
        holder = new BaseViewHolder(view);
        return holder;
    }


    @Override
    public void onBindViewHolder(BaseViewHolder holder, int position) {
        if (holder.getItemViewType() == BaseRecyPRAdapter.VIEW_PROG) {
//            LogTool.LogE_DEBUG(TAG, "onBindViewHolder--->" + mState);
            ProgressBar progressBar = (ProgressBar) holder.getView(R.id.progressbar);
            TextView text = (TextView) holder.getView(R.id.text);

            if (mState == STATE_LOAD_COMPLETE) {
                progressBar.setVisibility(View.GONE);
                text.setText(mContext.getString(R.string.沒有數據了));
            } else {
                progressBar.setVisibility(View.VISIBLE);
                text.setText(mContext.getString(R.string.正在加載中));
            }
        }

        if (holder.getItemViewType() == BaseRecyPRAdapter.VIEW_ITEM) {
            onBindData(holder, position);
        }
    }

    @Override
    public int getItemCount() {
        if (isShowFootVieW) {
            return mDataList == null ? 0 : mDataList.size() + 1;
        } else {
            return mDataList == null ? 0 : mDataList.size();
        }
    }


    //根據不同的數據返回不同的viewType
    @Override
    public int getItemViewType(int position) {
        if (mDataList == null)
            return VIEW_ITEM;

        if (position == mDataList.size()) {
            return VIEW_PROG;
        } else {
            return VIEW_ITEM;
        }
    }

    /**
     * 根據type 返回不同的佈局
     *
     * @param type
     * @return
     */
    public abstract int getLayoutId(int type);

    public abstract void onBindData(BaseViewHolder holder, int position);


    public static class BaseViewHolder extends RecyclerView.ViewHolder {
        private Map<Integer, View> mViewMap;
        public View view;

        public BaseViewHolder(View itemView) {
            super(itemView);

            view = itemView;
            mViewMap = new HashMap<>();
        }

        /**
         * 獲取設置的view
         *
         * @param id
         * @return
         */
        public View getView(int id) {
            View view = mViewMap.get(id);
            if (view == null) {
                view = itemView.findViewById(id);
                mViewMap.put(id, view);
            }
            return view;
        }
    }

    public void stopLoadMore() {
        mState = STATE_NORMAL;
        notifyDataSetChanged();
    }

    public void loadComplete() {
        mState = STATE_LOAD_COMPLETE;
        notifyItemChanged(getItemCount()-1);
    }

    public void setData(List<T> datas) {
        mDataList = datas;
    }

    private LoadMoreDataListener mLoadMoreDataListener;

    public void setLoadMoreDataListener(LoadMoreDataListener mLoadMoreDataListener) {
        this.mLoadMoreDataListener = mLoadMoreDataListener;
    }

    public interface LoadMoreDataListener {
        void loadMoreData();
    }
}

main xml的佈局如下:

<android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="none" />

item_foot xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="16dp"
    android:layout_marginTop="16dp"
    android:gravity="center_horizontal"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <ProgressBar
            android:id="@+id/progressbar"
            android:layout_width="28dp"
            android:layout_height="28dp" />

        <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dp"
            android:text=""
            android:textSize="16sp" />
    </LinearLayout>

</LinearLayout>

在activity的使用如下:
public class MainActivity extends AppCompatActivity {

private static final String TAG = "RecyActivity";
private RecyclerView mRecyclerView;
private List<String> list = new ArrayList<>();
private MyRecyViewAdapter mAdapter;
private Handler handler = new Handler();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    init();
}

private void init() {
    initView();
    initData();

    initListener();
}

private void initView() {
    mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);

    //創建一個LinearLayoutManager對象
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(
            this, LinearLayoutManager.VERTICAL, false);
    mRecyclerView.setLayoutManager(linearLayoutManager);

    //創建adapter對象
    mAdapter = new MyRecyViewAdapter(this, mRecyclerView);
    mRecyclerView.setAdapter(mAdapter);
    mAdapter.setData(list);//設置數據
}

//初始化數據
private void initData() {
    for (int i = 0; i < 15; i++) {
        list.add("DATA---------->" + i);
    }
}


//初始化監聽
private void initListener() {
    //加載更多回調監聽
    mAdapter.setLoadMoreDataListener(new BaseRecyPRAdapter.LoadMoreDataListener() {
        @Override
        public void loadMoreData() {
            //加入null值此時adapter會判斷item的type
            Log.e(TAG, "loadMoreData--->");
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (list.size() < 30) {
                        for (int i = 0; i < 5; i++) {
                            list.add("LOAD MORE DATA---------->" + i);
                        }
                        mAdapter.stopLoadMore();
                    } else {
                        mAdapter.loadComplete();
                    }
                }
            }, 500);
        }
    });
}

class MyRecyViewAdapter extends BaseRecyPRAdapter<String> {

    public MyRecyViewAdapter(Context context, RecyclerView recyclerView) {
        super(context, recyclerView);
    }

    @Override
    public int getLayoutId(int type) {
        return R.layout.item_view;
    }

    @Override
    public void onBindData(BaseViewHolder holder, int position) {
        Log.e(TAG, "onBindData--->" + position);
        if (mDataList == null || mDataList.isEmpty())
            return;

        TextView tv = (TextView) holder.getView(R.id.tv_name);
        if (tv != null) {
            tv.setText("DATA--------->" + position);
        }
    }
}

}

demo 下載地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章