前言
Android 项目开发中经常遇到列表式页面,并且需要实现下拉刷新,上拉到底后加载下一页的功能,这里结合我们项目正在使用的 MVP 框架,介绍一种基类封装方案,实现 View、Adapter、数据处理Presenter层的基类封装,后续继承这几个类,简单地重写下 UI 布局,网络请求即可实现下拉刷新,上拉加载功能。
老规矩,先上 Github 和 App 下载链接:
App下载地址: http://a.app.qq.com/o/simple.jsp?pkgname=chenyu.jokes
微信扫描下载APP:
App二维码
源码地址: https://github.com/zhongchenyu/jokes
由于后续代码可能会做重构,本文介绍的代码保存在 demo3_BaseScroll 分支,请 checkout。
View 层封装
View 层我们封装了 BaseScrollActivity 和 BaseScrollFragment 两个基类,分别用在需要使用 Activity 和 Fragment 的地方,这里先介绍下 BaseScrollActivity 。
UI 布局
要求所有继承的子类 Activity 必须包含一个 SwipeRefreshLayout ,再在其内部包含一个 RecyclerView。SwipeRefreshLayout 用于实现下拉刷新,而上拉加载需要通过 RecyclerView 的 OnScrollListener 实现。
<android.support.v4.widget.SwipeRefreshLayout android:id="@+id/refreshLayout"
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.v4.widget.SwipeRefreshLayout>
BaseScrollActivity 封装
再看一下 BaseScrollActivity 的代码:
package chenyu.jokes.base;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.Toast;
import butterknife.BindView;
import butterknife.ButterKnife;
import chenyu.jokes.R;
import java.util.ArrayList;
import nucleus.view.NucleusAppCompatActivity;
/**
* Created by chenyu on 2017/5/15.
*/
public abstract class BaseScrollActivity<Adapter extends BaseScrollAdapter, P extends BaseScrollPresenter, M>
extends NucleusAppCompatActivity<P> implements BaseRxView<M> {
@BindView(R.id.recyclerView) public RecyclerView recyclerView;
@BindView(R.id.refreshLayout) public SwipeRefreshLayout refreshLayout;
private int currentPage = 1;
private int previousTotal = 0;
private boolean loading = true;
private boolean noMoreData = false;
protected Adapter mAdapter;
protected boolean needLoadMore = true;
public abstract int getLayout();
public abstract Adapter getAdapter();
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayout());
ButterKnife.bind(this);
mAdapter = getAdapter();
recyclerView.setAdapter(mAdapter);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
}
@Override protected void onPostCreate(@Nullable Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
initListener();
getPresenter().loadPage(1);
}
private void initListener() {
refreshLayout.setColorSchemeResources(R.color.colorPrimary);
refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override public void onRefresh() {
mAdapter.clear();
getPresenter().loadPage(1);
currentPage = 1;
previousTotal = 0;
mAdapter.notifyDataSetChanged();
refreshLayout.setRefreshing(false);
}
});
if (needLoadMore) {
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (noMoreData) {
return;
}
int totalItemCount = recyclerView.getAdapter().getItemCount();
int lastVisibleItem =
((LinearLayoutManager) recyclerView.getLayoutManager()).findLastVisibleItemPosition()