内容简介:纵观多数App,下拉刷新和上拉加载更多是很常见的功能,但是谷歌官方只有一个SwipeRefreshLayout用来下拉刷新,上拉加载更多还要自己做。基于RecyclerView简单封装了这两个操作,下拉刷新支持LinearLayoutManager、GridLayoutManager和StaggeredGridLayoutManager;上拉加载更多只支持前两者。
纵观多数App,下拉刷新和上拉加载更多是很常见的功能,但是谷歌官方只有一个SwipeRefreshLayout用来下拉刷新,上拉加载更多还要自己做。
基于RecyclerView简单封装了这两个操作,下拉刷新支持LinearLayoutManager、GridLayoutManager和StaggeredGridLayoutManager;上拉加载更多只支持前两者。
话不多说先上效果图 数据来自 干货集中营
(下拉刷新)
(上拉加载更多 – LinearLayoutManager)
(上拉加载更多 – GridLayoutManager)
(一) 使用方式,很简单 如下:
- 1. 下拉刷新 3步走
1.1 布局文件
// 用SwipeRefreshLayout包裹RecyclerView <android.support.v4.widget.SwipeRefreshLayout android:id="@+id/gank_swipe_refresh_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/gank_recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" android:overScrollMode="never"/> </android.support.v4.widget.SwipeRefreshLayout>
1.2 给 SwipeRefreshLayout
添加监听 增加触发刷新时的操作(比如重新请求数据)
SwipeRefreshLayout swipeRefreshLayout = findViewById(); swipeRefreshLayout.setOnRefreshListener(new swipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { // do something, such as re-request from server or other } });
1.3 刷新操作(重新请求数据)完成后要回调来停止隐藏刷新动画(中上方圆形悬浮进度条旋转动画)
swipeRefreshLayout.setRefreshing(false);
至此下拉刷新完成
- 2.上拉加载3步走
2.1 初始化 AdapterWrapper
和 SwipeToLoadHelper
// adapter是你自己为RecyclerView写的Adapter RecyclerView.Adapter adapter = new YourOwnAdapter(); AdapterWrapper adapterWrapper = new AdapterWrapper(adapter); RecyclerView recyclerView = findViewById(); // 将RecyclerView和刚创建的adapterWrapper传入 SwipeToLoadHelper helper = new SwipeToLoadHelper(recyclerView, adapterWrapper);
2.2 设置加载动作触发后的监听
helper.setLoadMoreListener(new SwipeToLoadHelper.LoadMoreListener() { @Override public void onLoad() { // do something, such as request more data from server or other. } })
2.3 加载更多内容完成后要回调方法停止动画
helper.setLoadMoreFinish()
至此上拉加载完成 (注意更新数据时要调用 AdapterWrapper.notifyDataSetChanged
)
(二) 简明扼要的实现思路(上拉加载操作)
RecyclerView
的 itemView
的显示情况分为四种:
- 第1个可见的(部分显示或者完全显示都算可见)
- 第1个可见的且是完整的(完全显示算作完整的)
- 最后1个可见的
- 最后1个可见的且是完整的
-
1. 回弹效果
即手指抬起滑动停止,
上拉加载更多
部分显示时,将上拉加载更多
滚动到不显示,使上面挨着它的itemView
为最后1个可见且是最后1个完整可见。监听RecyclerView
的滚动,当RecyclerView
处于SCROLL_STATE_IDLE
状态时,获取最后1个完整可见的itemView
:如果是倒数第2个item
则计算该item
的下边距到RecyclerView
底部的距离deltaY
,然后将RecyclerView
向下滚动deltaY
;如果是上拉加载更多
则触发加载操作;其他情况不用处理。
// 关键代码 rv : recyclerView int lcp= layoutManager.findLastCompletelyVisibleItemPosition(); if (lcp == layoutManager.getItemCount() - 2) { // 倒数第2项 int fcp= layoutManager.findFirstCompletelyVisibleItemPosition(); View child = layoutManager.findViewByPosition(lcp); int deltaY = rv.getBottom() - rv.getPaddingBottom() - child.getBottom(); // fcp为0时说明列表滚动到了顶部, 不再滚动 if (deltaY > 0 && fcp!= 0) { rv.smoothScrollBy(0, -deltaY); } } else if (lcp== layoutManager.getItemCount() - 1) { // 最后一项完全显示, 触发操作, 执行加载更多操作 if (listener!= null) { listener.onLoad(); } }
-
2. 添加底部
加载更多
itemView
2.1 AdapterWrapper
重写了 getItemCount
方法,保证得到 itemView
的数量包括 加载更多
。当是 LinearLayoutManager
类型时直接加1;当是 GridLayoutManager
类型时,如果需要则先将列表最后一行填满,再加1。比如:列表每行有3个 itemView
,最后一行只有1个,这时就需要先加2,再加1,来保证 加载更多
占据完整的一行。
// 关键代码 其中的adapter为构造函数中传入的原生RecyclerView.Adapter if (adapterType == ADAPTER_TYPE_LINEAR) { // 线性布局 return adapter.getItemCount() + 1; } else { // 网格布局 spanCount为每行itemView的个数 int remain = adapter.getItemCount() % spanCount; // 余数 if (remain == 0) { return adapter.getItemCount() + 1; } // 余数不为0时,先凑满再加1 return adapter.getItemCount() + 1 + (spanCount - remain); }
2.2 AdapterWrapper
重写了 getItemViewType
方法,当是最后一个位置时返回 ITEM_TYPE_LOAD
// 关键代码 public int getItemViewType(int position) { // 位置是最后一个时, wrapper进行拦截 if (osition == getItemCount() - 1) { return ITEM_TYPE_LOAD;// 要避免和原生adapter返回值可能重复 } // 其他情况交给原生adapter处理 return adapter.getItemViewType(position); }
2.3 AdapterWrapper
重写了 onCreateViewHolder
方法,当类型为 ITEM_TYPE_LOAD
时返回 加载更多
的 ViewHolder
,其他情况交给原生的 adapter
处理。
// 关键代码 public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == ITEM_TYPE_LOAD) { return new LoadMoreHolder(); } else { return adapter.onCreateViewHolder(parent, viewType); } }
2.4 AdapterWrapper
重写了 onBindViewHolder
,这里有三种可能的情况:1. 正常的数据项 itemView
,交给 adapter
处理;2. GridView
的空白 itemView
,隐藏处理;3. 底部的 加载更多
,目前不需要做什么处理。
// 关键代码 public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (position == getItemCount() - 1) { } else if (position < adapter.getItemCount()){ adapter.onBindViewHolder(holder, position); } else { holder.itemView.setVisibility(View.INVISIBLE); } }
(三) 额外的两个说明
-
SwipeFreshLayout
有个setEnable(boolean)
方法,设置为false
的时候就下拉刷新功能就没有了,等同于普通的RecyclerView
-
同样
SwipeToLoadHelper
有个setSwipeToLoadEnabled(boolean)
方法,设置为false
的时候上拉加载功能就没有了, 等同于普通的RecyclerView
如有问题,欢迎指正~
附 项目仓库地址 ,如有需要请自取~
——————— 本文来自 是薛定谔啊 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/u012402124/article/details/78210639?utm_source=copy
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Swift iOS : 上拉刷新或者下拉刷新
- Swift iOS : 上拉刷新或者下拉刷新
- 上拉加载 下拉刷新
- 炫酷的列表下拉刷新效果
- Android中ListView下拉刷新的实现
- iOS 下拉刷新组件原理及简单实现
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
人件(原书第3版)
[美] Tom DeMarco、[美] Timothy Lister / 肖然、张逸、滕云 / 机械工业出版社 / 2014-8 / 69.00元
在软件管理领域,很少有著作能够与本书媲美。作为经久不衰的畅销书,本书深刻地洞察到软件开发的最大问题不在于技术,而在于人。人的因素并不容易解决,一旦解决了,你将更有可能获得成功。 本书是软件管理领域的传奇经典,被誉为“对美国软件业影响最大的一本书”。全书从管理人力资源、创建健康的办公环境、雇用并留用正确的人、高效团队形成、改造企业文化和快乐工作等多个角度阐释了如何思考和管理软件开发的最大问题—......一起来看看 《人件(原书第3版)》 这本书的介绍吧!