ByRecyclerView 提供了下拉刷新、上拉松手/自动加载更多、 添加HeaderView/FooterView、setStateView、item点击/长按、item局部刷新、万能分割线、粘性header、极简Adapter(databinding)等功能。
- 1.下拉刷新 / 支持SwipeRefreshLayout
- 2.自定义 下拉刷新布局 / 加载更多布局
- 3.加载更多机制:上拉松手 / 自动加载更多
- 4.Add HeaderView、FooterView、StateView
- 5.item及子view的点击/长按事件(防止重复点击)
- 6.item 局部刷新
- 7.优化过的BaseAdapter (RV/LV),减少大量代码
- 8.Adapter结合DataBinding/ViewBinding使用 (RV/LV)
- 9.可添加 万能分隔线(线性/宫格/瀑布流)
- 10.可配置 Skeleton骨架图
- 11.仿京东首页 RecyclerView嵌套滑动置顶示例
- 12.可配置自动加载更多机制 和 设置预加载条数
最新:setPageData()一行代码处理 列表显示数据和空视图
- 项目介绍 | wiki示例文档 | 更新日志 (1.4.1)
- ByRecyclerView:更方便的使用下拉刷新及加载更多
- ByRecyclerView:真·万能分割线 (线性/宫格/瀑布流)
- RecyclerView嵌套滑动置顶 项目应用篇
1.先在 build.gradle 的 repositories 添加
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
2.然后在dependencies添加
dependencies {
// AndroidX版本引入
implementation 'com.github.youlookwhat:ByRecyclerView:1.4.1'
}
3.在XML布局中引用 ByRecyclerView
<me.jingbin.library.ByRecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layoutManager="LinearLayoutManager"
tools:listitem="@layout/item_main" />
4.使用BaseRecyclerAdapter
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setAdapter(new BaseRecyclerAdapter<String>(R.layout.item_main, list) {
@Override
protected void bindView(BaseByViewHolder<String> holder, String bean, int position) {
holder.setText(R.id.tv_text, bean);
}
});
mAdapter.setNewData(list); // 设置第一页数据
5.设置监听
// 下拉刷新监听
mRecyclerView.setOnRefreshListener(new ByRecyclerView.OnRefreshListener() {
@Override
public void onRefresh() {
// 刷新完成
mRecyclerView.setRefreshing(false);
}
});
// 加载更多监听
mRecyclerView.setOnLoadMoreListener(new ByRecyclerView.OnLoadMoreListener() {
@Override
public void onLoadMore() {
mAdapter.addData(list); // 设置及刷新数据
mRecyclerView.loadMoreComplete(); // 加载更多完成
mRecyclerView.loadMoreEnd(); // 没有更多内容了
mRecyclerView.loadMoreFail(); // 加载更多失败,点击重试
}
});
6.显示数据
可直接调用adapter方法:setPageData(boolean isFirstPage, List<T> data, int emptyLayoutId)
/**
* 设置数据 和 处理空视图。
* 如果想列表上方显示状态视图(StateView),不能使用这个方法。
*
* @param isFirstPage 是否是第一页
* @param data 需要设置的数据
* @param emptyView 空视图的View
*/
public void setPageData(boolean isFirstPage, List<T> data, View emptyView) {
if (mRecyclerView == null) {
return;
}
if (isFirstPage) {
// 第一页
if (data != null && data.size() > 0) {
// 有数据
mRecyclerView.setStateViewEnabled(false);
mRecyclerView.setLoadMoreEnabled(true);
setNewData(data);
} else {
// 没数据,设置空布局
if (emptyView != null) {
mRecyclerView.setStateView(emptyView);
}
mRecyclerView.setLoadMoreEnabled(false);
setNewData(null);
}
} else {
// 第二页
if (data != null && data.size() > 0) {
// 有数据,显示更多数据
addData(data);
mRecyclerView.loadMoreComplete();
} else {
// 没数据,显示加载到底
mRecyclerView.loadMoreEnd();
}
}
}
为了适配更多的加载场景,我们增加了自动加载更多的机制,也可以设置预加载的条数,即滑动到倒数第preLoadNumber
条数据时执行加载更多,相比以前只用在设置监听时加上状态true
即可,使用方式:
void setOnLoadMoreListener(boolean isAutoLoadMore, OnLoadMoreListener listener)
void setOnLoadMoreListener(boolean isAutoLoadMore, int preLoadNumber, OnLoadMoreListener listener)
/**
* 设置加载更多监听
*
* @param isAutoLoadMore 是否自动加载
* @param preLoadNumber 自动加载时,默认滑动到倒数第[preLoadNumber]条数据加载,默认1
* @param listener 监听器
* @param delayMillis 延迟多少毫秒执行加载更多
*/
void setOnLoadMoreListener(boolean isAutoLoadMore, int preLoadNumber, OnLoadMoreListener listener, long delayMillis)
-
- 如果不设置,默认还是使用上拉松手加载更多机制
-
- 设置后如果想取消自动加载还是使用
recyclerView.setLoadMoreEnabled(false);
- 设置后如果想取消自动加载还是使用
-
- 不满一屏不加载更多
setNotFullScreenNoLoadMore()
,只对上拉松手加载更多有效
- 不满一屏不加载更多
万能分割线,可给Linear/Grid/StaggeredGrid设置,并可配置去除不显示分割线的头部和尾部个数
1.给LinearLayout设置分割线
// 选择1:设置drawable
SpacesItemDecoration itemDecoration = new SpacesItemDecoration(this, SpacesItemDecoration.VERTICAL)
.setNoShowDivider(1, 1) // 第一个参数:头部不显示分割线的个数,第二个参数:尾部不显示分割线的个数,默认为1
.setDrawable(R.drawable.shape_line);// 设置drawable文件
// 选择2:设置颜色、高度、间距等
SpacesItemDecoration itemDecoration = new SpacesItemDecoration(this, SpacesItemDecoration.VERTICAL)
.setNoShowDivider(1, 1)
// 颜色,分割线间距,左边距(单位dp),右边距(单位dp)
.setParam(R.color.colorBlue, 10, 70, 70);
recyclerView.addItemDecoration(itemDecoration);
2.给宫格/瀑布流设置分割线
// 10:间距; true:距屏幕周围是否也有间距
GridSpaceItemDecoration itemDecoration = new GridSpaceItemDecoration(10, true)
.setNoShowSpace(1, 1);// 第一个参数:头部不显示分割线的个数,第二个参数:尾部不显示分割线的个数,默认为1
recyclerView.addItemDecoration(itemDecoration);
// 获取view对应databinding,注意:recyclerView.getParent()
LayoutHeaderViewBinding headerBinding = DataBindingUtil.inflate(LayoutInflater.from(this), R.layout.layout_header_view, (ViewGroup) binding.recyclerView.getParent(), false);
recyclerView.addHeaderView(headerBinding.getRoot());
recyclerView.addFooterView(getView() / layoutId));
recyclerView.setStateView(getView() / layoutId);
// headerView、footerView、setStateView 支持一键隐藏,设置后需要notify
recyclerView.setHeaderViewEnabled(false);
recyclerView.setFootViewEnabled(false);
recyclerView.setStateViewEnabled(false);
// 防重复点击使用 OnItemFilterClickListener
mRecyclerView.setOnItemClickListener(new ByRecyclerView.OnItemClickListener() {
@Override
public void onClick(View v, int position) {
// 通过adapter获取对应position的数据
DataItemBean itemData = mAdapter.getItemData(position);
}
});
mRecyclerView.setOnItemLongClickListener(new ByRecyclerView.OnItemLongClickListener() {
@Override
public boolean onLongClick(View v, int position) {
return false;
}
});
// 添加 子View的点击/长按事件
holder.addOnClickListener(R.id.tv_text);
holder.addOnLongClickListener(R.id.tv_text);
// 防重复点击使用 OnItemChildFilterClickListener
recyclerView.setOnItemChildClickListener(new ByRecyclerView.OnItemChildClickListener() {
@Override
public void onItemChildClick(View view, int position) {
}
});
recyclerView.setOnItemChildLongClickListener(new ByRecyclerView.OnItemChildLongClickListener() {
@Override
public void onItemChildLongClick(View view, int position) {
}
});
// 设置要局部刷新的position及payload
adapter.refreshNotifyItemChanged(position, PayloadAdapter.PAYLOAD_COLLECT);
// adapter里额外再继承 bindViewPayloads 方法
@Override
protected void bindViewPayloads(@NonNull BaseBindingHolder holder, @NonNull DataItemBean bean, @NonNull ItemPayloadBinding binding, int position, @NonNull List<Object> payloads) {
for (Object p : payloads) {
int code = (int) p;
switch (code) {
case PAYLOAD_ZAN:
binding.tvZan.setText(bean.getIsZan() == 1 ? "已赞" : "点赞");
break;
case PAYLOAD_COLLECT:
binding.tvCollect.setText(bean.getIsCollect() == 1 ? "已收藏" : "收藏");
break;
default:
break;
}
}
}
// 1、使用StickyLinearLayoutManager,传入adapter
StickyLinearLayoutManager layoutManager = new StickyLinearLayoutManager(getContext(), mAdapter);
// 2、在adapter里,将悬浮的item的ItemViewType设置为StickyHeaderHandler.TYPE_STICKY_VIEW
@Override
public int getItemViewType(int position) {
if ("title".equals(getItemData(position).getType())) {
return StickyHeaderHandler.TYPE_STICKY_VIEW;
} else {
return 2;
}
}
1.设置item骨架图
// 显示
skeletonScreen = BySkeleton
.bindItem(binding.recyclerView)
.adapter(mAdapter)// 必须设置adapter,且在此之前不要设置adapter
.shimmer(false)// 是否有动画
.load(R.layout.layout_by_default_item_skeleton)// item骨架图
.angle(30)// 微光角度
.frozen(false) // 是否不可滑动
.color(R.color.colorWhite)// 动画的颜色
.duration(1500)// 微光一次显示时间
.count(10)// item个数
.show();
// 隐藏
skeletonScreen.hide();
2.设置view骨架图
// 显示
skeletonScreen = BySkeleton
.bindView(binding.recyclerView)
.load(R.layout.layout_skeleton_view)// view骨架图
.shimmer(true)// 是否有动画
.angle(20)// 微光角度
.color(R.color.colorWhite)// 动画的颜色
.duration(1500)// 微光一次显示时间
.show();
// 隐藏
skeletonScreen.hide();
- 1、由于 DataBinding 和 ViewBinding 最好别同时集成在项目里,所以新建了一个新的项目实践。
- 2、ViewBinding 对封装的不是很友好,demo里给的是没有进行反射处理的示例。
- 3、针对于 ListView 和 RecyclerView 的 adapter 都进行了封装。
- 4、推荐使用 DataBinding。
具体见项目:ByRv-viewbinding
ByRecyclerView | BRVAH | XRecyclerView | |
---|---|---|---|
下拉刷新布局 | 继承基类自定义布局 | 无 | 只能简单设置样式 |
SwipeRefreshLayout | 可配合使用 | 可配合使用 | 不能使用 |
加载更多布局 | 继承基类自定义布局 | 继承基类设置简单布局 | 继承基类自定义类 |
加载更多机制 | 上拉松手/自动加载更多 | 自动加载更多 | 上拉松手加载 |
HeaderView | 多ViewType区别 | 同一个item | 多ViewType区别 |
FooterView | 同一个item | 同一个item | 不能添加 |
EmptyView | 可设置 | 可设置 | 不可设置 |
点击/长按事件 | 有 | 有 | 无 |
ByRecyclerView 是XRecyclerView的拓展,可完全替换XRecyclerView,对于BRVAH它的区别在于:
- headerView使用的是多type的形式,即一个header就是一个position
- 可简单设置 上拉松手/自动加载更多 两种加载方式
- 自带下拉加载布局,也可使用三方刷新框架,比如SwipeRefreshLayout
- 万能分割线(LinearLayout / GridLayout / StaggeredGridLayout)
- 可设置Skeleton 骨架图
此资源库没有使用到任何序列化、反序列化、JNI、反射,无需进行额外的混淆操作,并且已经测试通过,在实际项目中使用,如果你在项目混淆之后出现问题,请及时联系我。
如果有任何问题,请到GitHub的issue处写上你不明白的地方,也可以通过下面提供的方式联系我,我会及时给予帮助。如果此库帮助到了你,欢迎点个star,非常感谢!
- QQ: 770413277
- 掘金:Jinbeen
- CSDN:Jinbeen
- Email: jingbin127@163.com
Copyright (C) 2016 Bin Jing
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.