想了解更多的请看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);