【版权申明】非商业目的注明出处可自由转载
博文地址:https://blog.csdn.net/ShuSheng0007/article/details/105779625
出自:shusheng007
前言
在日常从事Android开发工作时,经常会遇到下拉刷新列表页面,上拉自动加载列表的需求, GitHub上已经有很多关于这方面的功能极其强大的类库了,那我们还有必要自己写一个吗?
答案是:也许。因为那些类库实在是太重了!很多时候我们只使用了其5%的功能,但却不得不忍受剩下那95%的“无用”功能和复杂性。
UI方面,自己实现某些效果很多时候比直接使用现存类库更合适,关于这个话题这个不能深杠,世界上没有最好的东西,只有最适合的东西。
今天我们就简单介绍如何快速写一个一个既可下拉刷新,又可上滑无限加载的小巧灵活的UI控件。
InfiniteRecyclerView
一般情况下我们只使用Android原生提供的那些控件稍作组合或修改即可完成绝大部分UI需求,让我们看一下如何通过简单的组合Android原生的 SwipeRefreshLayout
和RecyclerView
来制作一个非常轻量而实用的控件。
下图只演示了无限加载功能:
准备实现的实用功能
- 下滑可以刷新页面
- 上滑可以无限加载
其实日常工作需求最多的也就上面两条。
实现思想
-
使用
SwipeRefreshLayout
套一个RecyclerView
,如下所示<androidx.swiperefreshlayout.widget.SwipeRefreshLayout android:id="@+id/container" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycle_view" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="vertical"/> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
SwipeRefreshLayout
负责下滑刷新,RecyclerView
, 负责上滑加载 -
通过
RecyclerView
的RecyclerView.OnScrollListener
来监听是否滑动到了最后一个item,如果滑动到了最后一个item则触发加载更多操作。private class OnScrollToBottomListener extends RecyclerView.OnScrollListener { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { ... if (manager instanceof LinearLayoutManager) { int lastCompletelyVisibleItemPosition = ((LinearLayoutManager) manager).findLastCompletelyVisibleItemPosition(); if (adapter.getItemCount() > 1 && lastCompletelyVisibleItemPosition >= adapter.getItemCount() - 1) { adapter.loadingMore(); } } else if (manager instanceof StaggeredGridLayoutManager) { int[] itemPositions = new int[2]; ((StaggeredGridLayoutManager) manager).findLastVisibleItemPositions(itemPositions); int lastVisibleItemPosition = (itemPositions[1] != 0) ? ++itemPositions[1] : ++itemPositions[0]; if (lastVisibleItemPosition >= adapter.getItemCount()) { adapter.loadingMore(); } } } ... }
- 当处于加载过程中时,在最后一行展示一个加载更多的 view
具体实现我觉得还是的自己看源代码吧,源代码就是我们程序员有效交流的最好语言。
如何使用
第一步:自定义一个
Adapter
,其需要继承RefreshRecycleAdapter<T>
, 例如下面这样public class BeautyListAdapter extends RefreshRecycleAdapter<Beauty> { public BeautyListAdapter(List<Beauty> dataSource) { super(dataSource); } @Override public RecyclerView.ViewHolder onCreateCustomViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_beauty,parent,false); return new BeautyViewHolder(view); } @Override public void onBindCustomViewHolder(RecyclerView.ViewHolder holder, int position) { BeautyViewHolder beautyViewHolder= (BeautyViewHolder) holder; final Beauty beauty=getList().get(position); beautyViewHolder.binding.ivBeautyHead.setImageResource(beauty.getPhotoId()); beautyViewHolder.binding.tvBeautyTitle.setText(beauty.getName()); beautyViewHolder.binding.tvBeautyIntroduction.setText(beauty.getIntroduction()); } static class BeautyViewHolder extends RecyclerView.ViewHolder{ private final ItemBeautyBinding binding; public BeautyViewHolder(@NonNull View itemView) { super(itemView); binding= ItemBeautyBinding.bind(itemView); } } }
Note:上面的代码使用了
viewBinding
功能,对此不熟悉的同学,推荐阅读Android开发之秒懂ViewBinding,一代神器ButterKnife的终结者第二步: 初始化控件并为其设置
Adapter
和LayoutManager
mAdapter = new BeautyListAdapter(mViewModel.dataSource); mBinding.pullRefreshList.setLayoutManager(new LinearLayoutManager(context)); mBinding.pullRefreshList.setAdapter(mAdapter); mAdapter.setOnRefreshLoadMoreListener(new AdapterLoader.OnRefreshLoadMoreListener() { @Override public void onRefresh() { //此处调用刷新逻辑 } @Override public void onLoadMore() { //此处调用加载更多逻辑 } });
第三步:处理结果
- 当刷新完成后使用如下代码告知控件刷新完成,去掉刷新的标志
mBinding.pullRefreshList.setRefresh(false);
- 当加载一页完成后,向数据源增加数据并刷新视图
mAdapter.notifyDataSetChanged();
当返回的列表为空时,说明已经没有数据了,此时使用如下方法通知控件已经到底了
mAdapter.setHasMore(false);
优势
- 轻量级
- 强可扩展性
你完全可以获取到SwipeRefreshLayout
和RecyclerView
,然后对他们进行各种骚操作。 - 使用简单,与
RecyclerView
的使用方法保持一致,只要会用RecyclerView
就可轻松使用(如果你说你只会用ListView,不会用RecyclerView,我只能对你漏出鄙夷的微笑了)。
总结
2020年突入其来的新冠病毒疫情已经肆虐了4个月了,很多受疫情影响的公司都快撑不住了,身边开始出现很多被裁员的同事和朋友,前两天亲眼目睹了一位被裁的同事情绪崩溃的样子,这件事也给自己敲响了警钟,单纯出卖自己的时间真的是一件很危险的事情,还是要不断的使自己增值,同时去找一件自己喜欢的事情,并坚持做下去。
耳边又想起了那个什么夫斯基的《钢铁是怎样炼成的》:
当他回首往事的时候,他不会因虚度年华而悔恨,也不会因碌碌无为而羞耻!
当我们回首往事的时候,往往会遗憾没有做过的事情,而不会悔恨做了什么事情。
源代码下载地址:InfiniteRecyclerview