Android中LRecyclerView的簡單使用
想了解更多的請看GitHub
第一步:填加依賴
Step 1. 在你的根build.gradle檔案中增加JitPack倉庫依賴。
allprojects {
repositories {
jcenter()
maven { url "https://jitpack.io" }
}
}
Step 2. 在你的module的build.gradle檔案中增加LRecyclerView依賴。
implementation 'com.github.jdsjlzx:LRecyclerView:1.4.3'
第二步:佈局
<com.github.jdsjlzx.recyclerview.LRecyclerView android:id="@+id/lrv" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_behavior="@string/appbar_scrolling_view_behavior"> </com.github.jdsjlzx.recyclerview.LRecyclerView>
第三步:介面卡Adapter
public class SuperViewHolder extends RecyclerView.ViewHolder { private SparseArray<View> views; public SuperViewHolder(View itemView) { super(itemView); this.views = new SparseArray<>(); } @SuppressWarnings("unchecked") public <T extends View> T getView(int viewId) { View view = views.get(viewId); if (view == null) { view = itemView.findViewById(viewId); views.put(viewId, view); } return (T) view; } }
public abstract class ListBaseAdapter<T> extends RecyclerView.Adapter<SuperViewHolder> { protected Context mContext; private LayoutInflater mInflater; protected ArrayList<T> mDataList = new ArrayList<>(); public ListBaseAdapter(Context mContext) { this.mContext = mContext; mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public SuperViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = mInflater.inflate(getLayoutId(), parent, false); return new SuperViewHolder(itemView); } @Override public void onBindViewHolder(SuperViewHolder holder, int position) { onBindItemHolder(holder, position); } //區域性重新整理關鍵:帶payload的這個onBindViewHolder方法必須實現 @Override public void onBindViewHolder(SuperViewHolder holder, int position, List<Object> payloads) { if (payloads.isEmpty()) { onBindViewHolder(holder, position); } else { onBindItemHolder(holder, position, payloads); } } public abstract int getLayoutId(); public abstract void onBindItemHolder(SuperViewHolder holder, int position); public void onBindItemHolder(SuperViewHolder holder, int position, List<Object> payloads){} @Override public int getItemCount() { return mDataList.size(); } /** * 獲得資料集合物件 * @return */ public List<T> getDataList() { return mDataList; } /** * 重新輸入集合資料 * @param list */ public void setDataList(Collection<T> list) { this.mDataList.clear(); this.mDataList.addAll(list); notifyDataSetChanged(); } /** * 新增一個集合的資料 * @param list */ public void addAll(Collection<T> list) { int lastIndex = this.mDataList.size(); if (this.mDataList.addAll(list)) { notifyItemRangeInserted(lastIndex, list.size()); } } /** * 新增一條資料 * @param item */ public void add(T item) { int lastIndex = this.mDataList.size(); if (this.mDataList.add(item)) { notifyItemRangeInserted(lastIndex, 1); } } /** * 刪除一條資料 * @param position */ public void remove(int position) { this.mDataList.remove(position); notifyItemRemoved(position); if(position != (getDataList().size())){ // 如果移除的是最後一個,忽略 notifyItemRangeChanged(position,this.mDataList.size()-position); } } /** * 清除資料 */ public void clear() { mDataList.clear(); notifyDataSetChanged(); } }
public class MyDefaultAdapter extends ListBaseAdapter<String> {//此泛型就是你的資料格式Bean
public MyDefaultAdapter(Context mContext) {
super(mContext);
}
@Override
public int getLayoutId() {
return R.layout.adapter_item;
}
@Override
public void onBindItemHolder(SuperViewHolder holder, int position) {
TextView textView=holder.getView(R.id.tv);
textView.setText(mDataList.get(position)+"");
}
}
第四步:在Activity中實現
adapter = new MyDefaultAdapter(this);
lRecyclerViewAdapter = new LRecyclerViewAdapter(adapter);
adapter.setDataList(list);//重新新增一個集合資料
// adapter.addAll(allList);//在之前資料的基礎上增加一個集合資料
// adapter.add("資料");//在之前資料的基礎上增加一條資料
// adapter.remove(2);//刪除指定下標的一條資料
// adapter.clear();//清除所有資料
LinearLayoutManager manager = new LinearLayoutManager(this);
mLrv.setLayoutManager(manager);
mLrv.setAdapter(lRecyclerViewAdapter);
- MyDefaultAdapter是使用者自己真正的adapter,使用者自己定義;
- LRecyclerViewAdapter提供了一些實用的功能,使用者不用關心它的實現,只需構造的時候把自己的adapter以引數形式傳進去即可。
第五步:程式碼混淆
#LRecyclerview
-dontwarn com.github.jdsjlzx.**
-keep class com.github.jdsjlzx.progressindicator.indicators.** { *; }
第六步:注意事項
1.如果添加了footerview,不要再使用setLScrollListener方法,如有需要,自定義實現即可。如下面程式碼不要同時使用:
mRecyclerView.setLScrollListener(LScrollListener);
mLRecyclerViewAdapter.addFooterView(new SampleFooter(this));
2.不要SwipeRefreshLayout與LRecyclerView一起使用,會有衝突,為了更好的滿足廣大使用者,新增了LuRecyclerView類,可以與SwipeRefreshLayout搭配使用,詳細請參考SwipeRefreshLayoutActivity類的實現。
3.關於RecyclerView自動滑動的問題
這個自動滑動歸根結底是焦點問題,子item有焦點,導致RecyclerView自動滑動到了子item,在根佈局上加了android:descendantFocusability="blocksDescendants",根view來處理焦點,不傳給子view就能解決問題。
4.關於LRecyclerView巢狀RecyclerView滑動卡頓的問題
可以參考:https://github.com/jdsjlzx/LRecyclerView/issues/165
第七步:其他功能
1. 新增HeaderView、FooterView
View header = LayoutInflater.from(this).inflate(R.layout.sample_header, (ViewGroup) findViewById(android.R.id.content), false);
lRecyclerViewAdapter.addHeaderView(header);
View footer = LayoutInflater.from(this).inflate(R.layout.sample_footer, (ViewGroup) findViewById(android.R.id.content), false);
lRecyclerViewAdapter.addFooterView(footer);
2. 移除HeaderView、FooterView
lRecyclerViewAdapter.removeHeaderView();
lRecyclerViewAdapter.removeFooterView();
注意:如果有兩個以上的HeaderView,連續呼叫mLRecyclerViewAdapter.removeHeaderView()即可。
3. LScrollListener-滑動監聽事件介面
- onScrollUp()——RecyclerView向上滑動的監聽事件;
- onScrollDown()——RecyclerView向下滑動的監聽事件;
- onScrolled()——RecyclerView正在滾動的監聽事件;
- onScrollStateChanged(int state)——RecyclerView正在滾動的監聽事件;
使用方式
mRecyclerView.setLScrollListener(new LRecyclerView.LScrollListener() {
@Override
public void onScrollUp() {
}
@Override
public void onScrollDown() {
}
@Override
public void onScrolled(int distanceX, int distanceY) {
}
@Override
public void onScrollStateChanged(int state) {
}
});
4. 下拉重新整理、載入更多
mLrv.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh() {
mLrv.refreshComplete(REQUEST_COUNT);//REQUEST_COUNT為每頁重新整理數量
lRecyclerViewAdapter.notifyDataSetChanged();
}
});
mLrv.setOnLoadMoreListener(new OnLoadMoreListener() {
@Override
public void onLoadMore() {
mLrv.refreshComplete(REQUEST_COUNT);//REQUEST_COUNT為每頁載入數量
lRecyclerViewAdapter.notifyDataSetChanged();
//如果沒有更多資料(也就是全部載入完成),加上如下程式碼:
mRecyclerView.setNoMore(true);
}
});
設定下拉重新整理樣式
mRecyclerView.setRefreshProgressStyle(ProgressStyle.BallSpinFadeLoader); //設定下拉重新整理Progress的樣式
mRecyclerView.setArrowImageView(R.drawable.iconfont_downgrey); //設定下拉重新整理箭頭
5. 設定下拉重新整理Header和Footer文字內容和顏色
//設定頭部載入顏色
mRecyclerView.setHeaderViewColor(R.color.colorAccent, R.color.dark ,android.R.color.white);
//設定底部載入顏色
mRecyclerView.setFooterViewColor(R.color.colorAccent, R.color.dark ,android.R.color.white);
//設定底部載入文字提示
mRecyclerView.setFooterViewHint("拼命載入中","已經全部為你呈現了","網路不給力啊,點選再試一次吧");
6. 開啟和禁止下拉重新整理、載入更多功能
mRecyclerView.setPullRefreshEnabled(true);
mRecyclerView.setLoadMoreEnabled(true);
7. 強制重新整理
mRecyclerView.forceToRefresh();
8. 當載入資料失敗時、網路異常出錯代時碼處理如下:
mRecyclerView.setOnNetWorkErrorListener(new OnNetWorkErrorListener() {
@Override
public void reload() {
requestData();
}
});
9. 點選事件和長按事件處理
mLRecyclerViewAdapter.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
}
});
mLRecyclerViewAdapter.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public void onItemLongClick(View view, int position) {
}
});
10. 設定空白View(setEmptyView)
mRecyclerView.setEmptyView(view);
11. 關於新增分割線
LinearLayoutManager佈局設定如下:
DividerDecoration divider = new DividerDecoration.Builder(this,mLRecyclerViewAdapter)
.setHeight(R.dimen.default_divider_height)
.setPadding(R.dimen.default_divider_padding)
.setColorResource(R.color.split)
.build();
mRecyclerView.addItemDecoration(divider);
GridLayoutManager佈局設定如下:
//第一種
int spacing = getResources().getDimensionPixelSize(R.dimen.dp_4);
mRecyclerView.addItemDecoration(SpacesItemDecoration.newInstance(spacing, spacing, manager.getSpanCount(), Color.GRAY));
//第二種
//根據需要選擇使用GridItemDecoration還是SpacesItemDecoration
GridItemDecoration divider = new GridItemDecoration.Builder(this)
.setHorizontal(R.dimen.default_divider_padding)
.setVertical(R.dimen.default_divider_padding)
.setColorResource(R.color.split)
.build();
//mRecyclerView.addItemDecoration(divider);