因为项目中多个列表都需要用到底部加载,所以我想了一个简单的底部加载方案。
先分析一下整个底部加载过程吧,首先为recyclerview设置滑动监听,recyclerview滑动时判断是否到达底部,到达就调用加载更多的方法。另外,还要控制加载过程的同步。
实现:
1.创建了一个类用来管理整个底部加载过程:
package sdu.edu.cn.utribe.bean;
import android.support.v7.widget.RecyclerView;
import sdu.edu.cn.utribe.util.Tool;
/**
* Created by lenovo on 2017/8/26.
*/
public class BottomManager {
private RecyclerView rv;
private Task task;
private boolean loading;
private boolean end;
public BottomManager(final RecyclerView rv, final Task task) {
this.rv = rv;
this.task = task;
this.end=false;
this.loading=false;
rv.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (loading||end){
return;
} else {
if (Tool.isSlideToBottom(rv))
{
loading=true;
new Thread(new Runnable() {
@Override
public void run() {
task.work();
}
}).start();
}
}
}
});
}
public boolean isLoading() {
return loading;
}
public void setLoading(boolean loading) {
this.loading = loading;
}
public boolean isEnd() {
return end;
}
public void setEnd(boolean end) {
this.end = end;
}
public RecyclerView getRv() {
return rv;
}
public void setRv(RecyclerView rv) {
this.rv = rv;
}
public interface Task{
void work();
}
}
Tool.isSlideToBottom是我写在工具类里的一个静态方法,根据recyclerview的滑动距离判断是否到底。
//判断列表是否滑到底部
public static boolean isSlideToBottom(RecyclerView recyclerView) {
if (recyclerView == null) return false;
if (recyclerView.computeVerticalScrollExtent() + recyclerView.computeVerticalScrollOffset() >= recyclerView.computeVerticalScrollRange())
return true;
return false;
}
2.activity中的使用:
创建一个BotomManager实例,传入目标列表和加载更多的方法
manager=new BottomManager(rv, new BottomManager.Task() {
@Override
public void work() {
getData();
}
});
在加载更多的方法中,加载完毕后设置manager的loading为false,如果获取到的是空数组设置end为true(这里用了retrofit和gson)
private void getData(int offsets) {
appUrl.getMyTieziList(page,rows,offsets).subscribe(new Subscriber<ResponseBody>() {
@Override
public void onCompleted() {
manager.setLoading(false);
handler.post(new Runnable() {
@Override
public void run() {
adapter.notifyDataSetChanged();
}
});
}
@Override
public void onError(Throwable e) {
Log.v("tag","我的帖子error:"+e.getMessage());
}
@Override
public void onNext(ResponseBody responseBody) {
try {
String s=responseBody.string();
JSONObject obj=new JSONObject(s);
switch (obj.getInt("status")){
case 200://请求成功
Type listType = new TypeToken<List<TieziItem>>(){}.getType();
List<TieziItem> list1= new Gson().fromJson(obj.getString("data"),listType);
Log.v("tag","我的帖子:"+obj.getString("data"));
if (list1.size()<=0){
manager.setEnd(true);
}
list.addAll(list1);
break;
case 300:
break;
case 400:
break;
}
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
3.其他
scroll.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
@Override
public void onScrollChange(NestedScrollView v, int i, int scrollY, int i2, int i3) {
if (scrollY == (v.getChildAt(0).getMeasuredHeight() - v.getMeasuredHeight())) {
//底部加载
Log.v("tag","底部加载");
rvBottom();
}
}
});