今天终于有点时间,来写了一下: 为RecyclerView实现下拉刷新和上拉加载更多。今天会在前面的两篇文章的基础上:
RecyclerView系列之(1):为RecyclerView添加Header和Footer
RecyclerView系列之(2):为RecyclerView添加分隔线
继续讲述RecyclerView中一些常用组件的实现下拉刷新和上拉加载更多的功能。
在现在的Android手机应用中,几乎每一个APP都有下拉刷新和上拉加载更多的功能,它们的重要性不言而喻。
先不多说,先看效果图:
下拉刷新和上拉加载这两个功能,一开始给人的感觉就是它们是一个组合,它们之间是不是存在什么关系,但是事实上,实现的方式是完全不一样的。下面我将结合核心部分代码来讲一下它们的实现。
一. 实现下拉刷新
在google的android.support.v4包中,提供一个SwipeRefreshLayout方法, 用于实现下拉刷新,实现的过程也非常简单, 那我们先来看一下SwipeRefreshLayout是什么东西,其实从名字上来看,它就是一个刷新布局,我们来看它的继承结构图:
从上面的继承结构可以看出, 它继承于:ViewGroup. 而我们常见的LinearLayout, GridLayout等常见的布局,也是继承于ViewGroup。所以它的使用方法和我们常见的差不多,我们想要刷新下拉刷新我们的RecyclerView, 那我们就要将我们的RecyclerView布局文件放到SwipeLayout中。
而在SwipeRefleshLayout中,它又提供了一个接口:SwipeRefreshLayout.OnRefreshListener, 并且在这个口里面提供了一个抽象方法:onRefresh(), 到这里, 我们大概知道它是怎么运作的了,我们只需要在Activity中,实现这个接口,并且实现OnRefresh()方法即可,在onReflesh()方法中,进行我们的刷新数据操作,下面直接来看主要代码:
在主布局中的文件:加入以下代码:
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/layout_swipe_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>
就是SwipeRefreshLayout中包含我们的recyclerView
在Activity中
实现以下核心代码:
- 创建一个SwipeRefreshLayout对象,在onCreate()方法中初始化
mRefreshLayout = (SwipeRefreshLayout)findViewById(R.id.layout_swipe_refresh); - 为其添加SwipeRefreshLayout.OnRefreshListener事件:
mRefreshLayout.setOnRefreshListener(new OnRefreshListener(){
public void onRefresh() {
//我在List最前面加入一条数据
mData.add(0, "嘿,我是“下拉刷新”生出来的");
//数据重新加载完成后,提示数据发生改变,并且设置现在不在刷新
mAdapter.notifyDataSetChanged();
mRefreshLayout.setRefreshing(false);
}
});
到这里,就实现了下拉刷新的功能,具体的Adapter的实现,分隔线的加入,请看我前面的两篇文章,或者是看后面附带的源码
这样,我们就实现了下拉刷新的功能,下面再来实现上拉加载更多的功能。
二. 上拉加载更多
上拉加载,主要实现的是一个类似分页的功能,不能一开始的时候就加载全部数据,如果数据很多,或者是网络速度慢的话,这需要很久的时间才能加载完成。而上拉加载的思想是:我一开始的时候,就给你加载二十条数据左右,如果你还想看下面的数据的画,再次进行加载二十条,分批次加载,这样就提升了用户体验。
public class MainActivity extends AppCompatActivity {
List<Integer> data=new ArrayList<Integer>();
SwipeRefreshLayout swipeRefreshLayout;
RecyclerView recyclerView;
MyAdapter adapter;
boolean flag=true; //数据是否更新完成的标志
LinearLayoutManager layoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
swipeRefreshLayout=(SwipeRefreshLayout)findViewById(R.id.swipe);
recyclerView=(RecyclerView)findViewById(R.id.recycler);
initData();
layoutManager=new LinearLayoutManager(MainActivity.this);
//linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager); //要在setAdapter之前setLayoutManager
adapter=new MyAdapter(data);
recyclerView.setAdapter(adapter);
/**
* 上拉加载功能的实现
*/
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
int number=20; //下一次更新的数据条数
int maxpage=5; //更新的总的最大页数
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
//每下拉一部分就执行onScrolled的方法
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int visibleTotal=layoutManager.getChildCount(); //整个屏幕内可视item的条数
int itemTotal=layoutManager.getItemCount(); //总的item的数量
int firstItemPosition=layoutManager.findFirstVisibleItemPosition();//可视的第一个item的位置
//判断是否下拉至最底部并且数据更新完成
if (firstItemPosition+visibleTotal>=itemTotal&&flag){
/**
* 当前数据处于的页数(从0开始)
* 例如item总数为10,更新数据条数为20,则10%20=0,则处于第10/20=0页
* 例如item总数为20,更新数据条数为20,则20%20=0,则处于第20/20=1页
* 例如item总数为100,更新数据条数为20,则100%20=0,则处于第100/20=5页
*
* 例如item总数为101,更新数据条数为20,则101%20=1,则处于第101/20+1=6页
*/
int currentpage=itemTotal%number==0?itemTotal/number:itemTotal/number+1;
int nextpage=currentpage+1; //即将翻开的下一页的数目
if (nextpage<=maxpage&&flag){ //判断下一页是否超过总的限制的页数并且是否刷新完成
flag=false; //刷新标志设置为false,开始刷新
addData(); //添加刷新数据
}
}
}
});
/**
* 上拉加载(因为数据加载需要时间,所以应在子线程中运行,但是显示数据需要在主线程中,即runOnUiThread)
*/
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
try {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);//模拟通过网络获取数据
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
initData();
adapter.notifyDataSetChanged();
swipeRefreshLayout.setRefreshing(false);
}
});
}
}).start();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* 子线程上拉添加数据
*/
private void addData() {
new Thread(new Runnable() {
@Override
public void run() {
for (int i=0;i<20;i++){
Integer r= Integer.valueOf((int) (Math.random()*100));
data.add(r);
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
adapter.notifyDataSetChanged();
flag=true;
}
});
}
}).start();
}
/**
* 初始化第一次打开时的数据
*/
private void initData() {
data.clear();
for (int i=0;i<40;i++){
Integer r= Integer.valueOf(i);
data.add(r);
}
}
}
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
List<Integer> data=new ArrayList<Integer>();
static class MyViewHolder extends RecyclerView.ViewHolder{
TextView textView;
public MyViewHolder(View itemView) {
super(itemView);
this.textView=itemView.findViewById(R.id.item_text);
}
}
public MyAdapter(List<Integer> data) {
super();
this.data=data;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.item,null);
MyViewHolder myViewHolder=new MyViewHolder(view);
return myViewHolder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Integer da=data.get(position);
holder.textView.setText(da+"");
}
@Override
public int getItemCount() {
return data.size();
}
}
到这里,我们的整个RecyclerView系列之(3)就实现了, 这三篇文章,它能做到的,ListView都可以做到,并没有体现出RecyclerView的灵活性,关于RecyclerView的灵活性, 很多人会想到一个词:瀑布流,看下图
而下一篇文章我会带来RecyclerView瀑布流的实现,谢谢咯。
最近挺忙,但是忙也不是不写文章的借口。
作者:右眼皮的爱
链接:http://www.jianshu.com/p/3bf125b4917d
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
本文详细介绍如何在Android应用中为RecyclerView实现下拉刷新及上拉加载更多功能。利用SwipeRefreshLayout实现下拉刷新效果,通过监听滚动事件实现上拉加载。文章提供了完整的代码示例。
160

被折叠的 条评论
为什么被折叠?



