您的位置:首页 > 其它

给RecyclerView最纯粹的下拉刷新和上拉加载更多

2016-08-16 23:11 351 查看
RecyclerView 出现以后,Android 里的下拉刷新和加载更多实现起来就非常容易了。当然,现成的库也有很多,只是总会有不一样的需求,而且我们往往只需要最基本的下拉刷新和加载更多功能,而不需要其他多余的功能。我只需要一个最纯粹的下拉刷新和加载更多。所以,自己动手显然是最好的结果了,也算是个小练习。总结起来,无非两点,一是用 SwipeRefreshLayout 包裹 RecyclerView 实现下拉刷新,二是滑倒底部的时候自动加载实现加载更多。
需要注意的是两点:
下拉刷新是通过实现 SwipeRefreshLayout.OnRefreshListener 接口来实现的,也就是说下拉刷新具有了通用性,不只是 RecyclerView ;
加载更多要通过 LinearLayoutManager 来获取 RecyclerView 是否滑动到底部来实现。
这样我们就把问题分解了。第一步,我们先看最简单的下拉刷新,由于代码过于简单,我就直接贴代码了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);
swipeRefreshLayout.setColorSchemeResources(
R.color.google_blue,
R.color.google_green,
R.color.google_red,
R.color.google_yellow
);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(linearLayoutManager);
setData();
RefreshAdapter refreshAdapter = new RefreshAdapter(mList, this);
recyclerView.setAdapter(refreshAdapter);
swipeRefreshLayout.setOnRefreshListener(this);
}

private void setData() {
mList = new ArrayList<>();
for (int i = 0; i < 20; i++) {
mList.add("第" + i + "个");
}
}

@Override
public void onRefresh() {
Observable
.timer(2, TimeUnit.SECONDS, AndroidSchedulers.mainThread())
.map(new Func1<Long, Object>() {
@Override
public Object call(Long aLong) {
fetchingNewData();
swipeRefreshLayout.setRefreshing(false);
refreshAdapter.notifyDataSetChanged();
Toast.makeText(MainActivity.this, "Refresh Finished!", Toast.LENGTH_SHORT).show();
return null;
}
}).subscribe();
}

private void fetchingNewData() {
mList.add(0, "下拉刷新出来的数据");
}

然后就是加载更多功能,RecyclerView 有一个方法 addOnScrollListener ,我们只要传入一个RecyclerView.OnScrollListener 就可以实现加载更多了,但是事实是为了充分保证 RecyclerView 的灵活性,Android 本身是没有对这个滑动接口做处理的,需要我们自定义个加载更多的接口去实现它,然后才能真正实现加载更多。实现起来也很简单,我们只要重写 onScrolled 方法即可。下面是一个封装好的加载更多的接口实现类,然后作为参数传进去就好了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

public abstract class EndlessRecyclerOnScrollListener extends
RecyclerView.OnScrollListener {

private int previousTotal = 0;
private boolean loading = true;
int firstVisibleItem, visibleItemCount, totalItemCount;

private int currentPage = 1;

private LinearLayoutManager mLinearLayoutManager;

public EndlessRecyclerOnScrollListener(
LinearLayoutManager linearLayoutManager) {
this.mLinearLayoutManager = linearLayoutManager;
}

@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);

visibleItemCount = recyclerView.getChildCount();
totalItemCount = mLinearLayoutManager.getItemCount();
firstVisibleItem = mLinearLayoutManager.findFirstVisibleItemPosition();

if (loading) {
if (totalItemCount > previousTotal) {
loading = false;
previousTotal = totalItemCount;
}
}
if (!loading
&& (totalItemCount - visibleItemCount) <= firstVisibleItem) {
currentPage++;
onLoadMore(currentPage);
loading = true;
}
}

public abstract void onLoadMore(int currentPage);
}

然后就是具体的加载更多的实现逻辑了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

recyclerView.addOnScrollListener(new EndlessRecyclerOnScrollListener(linearLayoutManager) {
@Override
public void onLoadMore(int currentPage) {
simulateLoadMoreData();
}
});

private void simulateLoadMoreData() {
Observable
.timer(2, TimeUnit.SECONDS, AndroidSchedulers.mainThread())
.map(new Func1<Long, Object>() {
@Override
public Object call(Long aLong) {
loadMoreData();
stringAdapter.notifyDataSetChanged();
Toast.makeText(MainActivity.this, "Load Finished!", Toast.LENGTH_SHORT).show();
return null;
}
}).subscribe();
}

private void loadMoreData() {
List<String> moreList = new ArrayList<>();
for (int i = 10; i < 13; i++) {
moreList.add("加载更多的数据");
}
mList.addAll(moreList);
}

这样,下拉刷新和加载更多就实现了,就这么简单。
当然,如果你想要一个加载更多的 ProgressBar 展示的话,可以给 RecyclerView 添加一个 Footer ,用来展示加载更多的过程。GitHub 上搜索一下会有很多实现方案,这里我随便贴一个作为例子。HeaderViewRecyclerAdapter,一个用起来相当方便的
Gist ,如果用在上面的例子里就会是这样:
1
2
3
4
5
6
7
8
9
10

HeaderViewRecyclerAdapter stringAdapter = new HeaderViewRecyclerAdapter(refreshAdapter);
recyclerView.setAdapter(stringAdapter);
createLoadMoreView();

private void createLoadMoreView() {
View loadMoreView = LayoutInflater
.from(MainActivity.this)
.inflate(R.layout.view_load_more, recyclerView, false);
stringAdapter.addFooterView(loadMoreView);
}

然后把对应的 adapter 替换以后即可。代码看这里SwipeRefreshRecyclerView
我们可以看到运行效果非常完美




#RecyclerView #下拉刷新 #加载更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: