开篇
工作闲暇之余,用SwipeRefreshLayout+RecyclerView倾心打造了一个下拉刷新控件分享给童鞋们。我给此组件命名为SwipeRefreshRecyclerView。
这是我的另一篇文章:打造类似SwipeRefreshLayout的下拉刷新控件
屏幕截图
SwipeRefreshRecyclerView之亮点:
- 支持下拉刷新(可开关)
- 支持下拉加载更多(可开关)
- 支持自定义空列表视图(EmptyView)
- 可自定义加载更多(包括视图LoadMoreView、动画、逻辑)
- 支持各种LayoutManager(仅限于VERTICAL方向)的RecyclerView:
LinearLayoutManager
、GridLayoutManager
、StaggeredGridLayoutManager
- 纯代码封装、简洁清晰高性能、使用方便
立即体验
扫描以下二维码下载体验App(从0.2.3
版本开始,体验App内嵌版本更新检测功能):
JSCKit库传送门:https://github.com/JustinRoom/JSCKit
源码简析
SwipeRefreshRecyclerView关键逻辑(请参阅以下代码里的注释):
//下拉刷新监听
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
isLoading = true;
if (customRefreshListener != null) {
customRefreshListener.onRefresh();
}
}
});
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
RecyclerView.Adapter adapter = recyclerView.getAdapter();
if (layoutManager == null || adapter == null) {
swipeRefreshLayout.setEnabled(false);
return;
}
boolean isFirstItemVisiable;
boolean isLastItemVisiable;
int itemCount = adapter.getItemCount();
//GridLayoutManager是继承LinearLayoutManager的。
if (layoutManager instanceof LinearLayoutManager) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
//竖直方向,不可下拉刷新,也不可上拉加载更多
if (linearLayoutManager.getOrientation() == LinearLayoutManager.HORIZONTAL){
swipeRefreshLayout.setEnabled(false);
return;
}
//判断是否空列表或者已下拉至列表顶部
isFirstItemVisiable = (itemCount == 0 || linearLayoutManager.findFirstCompletelyVisibleItemPosition() == 0);
//判断是否上拉至列表底部
isLastItemVisiable = linearLayoutManager.findLastCompletelyVisibleItemPosition() + 1 == itemCount;
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;
//竖直方向,不可下拉刷新,也不可上拉加载更多
if (staggeredGridLayoutManager.getOrientation() == LinearLayoutManager.HORIZONTAL){
swipeRefreshLayout.setEnabled(false);
return;
}
int[] firstItemPositions = staggeredGridLayoutManager.findFirstCompletelyVisibleItemPositions(null);
// Log.i(TAG, "onScrolled: " + Arrays.toString(firstItemPositions));
//判断是否空列表或者已下拉至列表顶部
isFirstItemVisiable = itemCount == 0 || (firstItemPositions.length > 0 && firstItemPositions[0] == 0);
int[] lastItemPositions = staggeredGridLayoutManager.findLastCompletelyVisibleItemPositions(null);
//判断是否上拉至列表底部
isLastItemVisiable = lastItemPositions.length > 0 && (lastItemPositions[lastItemPositions.length - 1] + 1 == itemCount);
} else {
return;
}
swipeRefreshLayout.setEnabled(isRefreshEnable() && isFirstItemVisiable);
if (isLoading || !isLoadMoreEnable() || !isHaveMore || !isLastItemVisiable)
return;
//处理加载更多的动画以及逻辑
if (customRefreshListener != null) {
isLoading = true;
//show your custom loading more animation.
if (customLoadMoreAnimationListener != null)
customLoadMoreAnimationListener.onLoadMoreStartAnim(SwipeRefreshRecyclerView.this, customRefreshListener);
else
showScrollUpAnim();
}
}
});
公共方法
用法
int pageSize = 24;//一页最多可显示的数据数
int pageIndex = 1;//页码
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_swip_recycler_view);
swipeRefreshRecyclerView = findViewById(R.id.swipe_recycler_view);
//添加LayoutManager
// swipeRefreshRecyclerView.setLayoutManager(new LinearLayoutManager(this));
swipeRefreshRecyclerView.setLayoutManager(new GridLayoutManager(this, 2, RecyclerView.VERTICAL, false));
// swipeRefreshRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, RecyclerView.VERTICAL));
//添加ItemDecoration
DividerItemDecoration decoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL);
decoration.setDrawable(getResources().getDrawable(R.drawable.item_decoration_shape));
swipeRefreshRecyclerView.getRecyclerView().addItemDecoration(decoration);
//
swipeRefreshRecyclerView.getSwipeRefreshLayout().setColorSchemeColors(0xFF3F51B5, 0xFF303F9F, 0xFFFF4081, Color.CYAN);
//设置自定义的emptyView
int topMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 64, getResources().getDisplayMetrics());
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.CENTER_HORIZONTAL;
params.topMargin = topMargin;
swipeRefreshRecyclerView.setEmptyView(createEmptyView(), params);
//设置自定义的loadMoreView
swipeRefreshRecyclerView.setLoadMoreView(createLoadMoreView());
//添加刷新或者加载更多监听
swipeRefreshRecyclerView.setCustomRefreshListener(new SwipeRefreshRecyclerView.OnCustomRefreshListener() {
@Override
public void onRefresh() {
pageIndex = 1;
//模拟请求网络数据
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
swipeRefreshRecyclerView.refreshComplete();
List<Banner> banners = getRandomBanners();
adapter.setItems(banners);
//是否还有下一页数据
swipeRefreshRecyclerView.setHaveMore(banners.size() >= pageSize);
//是否显示empty view
swipeRefreshRecyclerView.showEmptyViewIfNecessary();
}
}, 3000);
}
@Override
public void onLoadMore() {
pageIndex ++;
//模拟请求网络数据
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
swipeRefreshRecyclerView.loadMoreComplete();
List<Banner> banners = getRandomBanners();
adapter.addItems(banners);
//是否还有下一页数据
swipeRefreshRecyclerView.setHaveMore(banners.size() >= pageSize);
}
}, 3000);
}
});
//自定义“加载更多” 的动画(或逻辑)。请参照SwipeRefreshRecyclerView默认的动画(或逻辑):showScrollUpAnim()、showScrollDownAnim()
//如果只用SwipeRefreshRecyclerView默认的动画(或逻辑)。不设置OnCustomLoadMoreAnimationListener或者设置为null即可。
/*
swipeRefreshRecyclerView.setCustomLoadMoreAnimationListener(new SwipeRefreshRecyclerView.OnCustomLoadMoreAnimationListener() {
@Override
public void onLoadMoreStartAnim(@NonNull final SwipeRefreshRecyclerView swipeRefreshRecyclerView, final SwipeRefreshRecyclerView.OnCustomRefreshListener refreshListener) {
final SwipeRefreshLayout layout = swipeRefreshRecyclerView.getSwipeRefreshLayout();
final View loadMoreView = swipeRefreshRecyclerView.getLoadMoreView();
// TODO: 4/9/2018
}
@Override
public void onLoadMoreCompleteAnim(@NonNull final SwipeRefreshRecyclerView swipeRefreshRecyclerView, final SwipeRefreshRecyclerView.OnCustomRefreshListener refreshListener) {
final SwipeRefreshLayout layout = swipeRefreshRecyclerView.getSwipeRefreshLayout();
final View loadMoreView = swipeRefreshRecyclerView.getLoadMoreView();
// TODO: 4/9/2018
}
});
*/
adapter = new LinearAdapter();
//设置适配器
swipeRefreshRecyclerView.setAdapter(adapter);
//300毫秒后自动刷新
swipeRefreshRecyclerView.refreshDelay(300);
}
篇尾
如果您觉得还不错的话,给个star(或加个关注)啰!我是JustinRoom,QQ:1006368252。
新的数学方法和概念,常常比解决数学问题本身更重要。 —— 华罗庚
网友评论