前 言
在Android影视或者资讯类等应用中都有下拉刷新数据和上拉加载更多数据的功能,还有我们日常生活中刷新朋友圈和刷微博都接触到这两个功能,可以说下拉刷新数据和上拉加载更多数据的功能是Android应用中必不可少的功能。那么,下面就来看看这两个功能是如何实现的吧。
在 AS Gradle 里添加相关的上拉刷新、下拉加载更多数据依赖库
在内层build.gradle里添加
dependencies {
........
// 上拉刷新、下拉加载更多数据
implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0-alpha-21'
implementation 'com.scwang.smartrefresh:SmartRefreshHeader:1.1.0-alpha-21'
}
该上拉刷新、下拉加载更多数据依赖库的地址是 https://github.com/scwang90/SmartRefreshLayout ,有兴趣的朋友可以到该仓库的GitHub地址里去看看,里面有详细的使用文档。
编码实现
public class MainActivity extends BaseActivity {
@BindView(R
.id
.loading_view
)
ImageView mLoadingView
;
@BindView(R
.id
.homeMovieList
)
RecyclerView homeMovieList
;
@BindView(R
.id
.refreshLayout
)
RefreshLayout refreshLayout
;
@BindView(R
.id
.loading_view_ll
)
LinearLayout loading_view_ll
;
@BindView(R
.id
.error_view
)
RelativeLayout error_view
;
private boolean refreshType
;
private int page
;
private int oldListSize
;
private int newListSize
;
private int addListSize
;
private MovieAdapter adapter
;
private List
<MovieDataModel> mList
= new ArrayList<>();
@Override
protected int getLayoutId() {
return R
.layout
.activity_main
;
}
@Override
protected void initView() {
ButterKnife
.bind(this);
AnimationDrawable anim
= (AnimationDrawable
) mLoadingView
.getDrawable();
anim
.start();
}
@Override
protected void initData() {
refreshLayout
.setEnableAutoLoadMore(true);
refreshLayout
.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh(@NonNull final RefreshLayout refreshLayout
) {
refreshLayout
.getLayout().postDelayed(new Runnable() {
@Override
public void run() {
refreshType
= true;
page
= 1;
movieListRequest(page
);
refreshLayout
.finishRefresh();
refreshLayout
.resetNoMoreData();
}
}, 2000);
}
});
refreshLayout
.setOnLoadMoreListener(new OnLoadMoreListener() {
@Override
public void onLoadMore(@NonNull final RefreshLayout refreshLayout
) {
refreshLayout
.getLayout().postDelayed(new Runnable() {
@Override
public void run() {
refreshType
= false;
if (page
> 2) {
ToastUtil
.showToast("暂无更多的数据啦");
refreshLayout
.finishLoadMoreWithNoMoreData();
return;
}
movieListRequest(page
);
refreshLayout
.setEnableLoadMore(false);
refreshLayout
.finishLoadMore();
}
}, 2000);
}
});
refreshLayout
.autoRefresh();
}
private void movieListRequest(int page
) {
String url
= String
.format(HttpConstants
.MOVIE_URL
, page
);
OkHttpUtils
.excute(url
, new Callback() {
@Override
public void onFailure(Call call
, IOException e
) {
L
.i("onFailure:" + e
.getMessage());
e
.printStackTrace();
runOnUiThread(new Runnable() {
@Override
public void run() {
error_view
.setVisibility(View
.VISIBLE
);
homeMovieList
.setVisibility(View
.GONE
);
loading_view_ll
.setVisibility(View
.GONE
);
ToastUtil
.showToast("服务器异常,数据请求失败");
}
});
}
@Override
public void onResponse(Call call
, Response response
) throws IOException
{
String res
= response
.body().string();
L
.i("onResponse:" + res
);
runOnUiThread(new Runnable() {
@Override
public void run() {
parsingMovieListJson(res
);
}
});
}
});
}
private void parsingMovieListJson(String t
) {
if (refreshType
) {
mList
.clear();
oldListSize
= 0;
} else {
oldListSize
= mList
.size();
}
Gson gson
= new Gson();
MovieBaseModel movieBaseModel
= gson
.fromJson(t
, MovieBaseModel
.class);
List
<MovieDataModel> movieDataModelList
= movieBaseModel
.getData();
for (MovieDataModel movieDataModel
: movieDataModelList
) {
MovieDataModel data
= new MovieDataModel();
data
.setMovieName(movieDataModel
.getMovieName());
data
.setPoster(movieDataModel
.getPoster());
data
.setTag(movieDataModel
.getTag());
data
.setUpdateStatus(movieDataModel
.getUpdateStatus());
mList
.add(data
);
}
newListSize
= mList
.size();
addListSize
= newListSize
- oldListSize
;
if (refreshType
) {
homeMovieList
.setLayoutManager(new GridLayoutManager(this, 3));
adapter
= new MovieAdapter(this, mList
);
homeMovieList
.setAdapter(adapter
);
} else {
adapter
.notifyItemRangeInserted(mList
.size() - addListSize
, mList
.size());
adapter
.notifyItemRangeChanged(mList
.size() - addListSize
, mList
.size());
refreshLayout
.setEnableLoadMore(true);
}
page
++;
homeMovieList
.setVisibility(View
.VISIBLE
);
error_view
.setVisibility(View
.GONE
);
loading_view_ll
.setVisibility(View
.GONE
);
adapter
.setItemClikListener(new MovieAdapter.OnItemClikListener() {
@Override
public void onItemClik(View view
, int position
) {
String movieName
= mList
.get(position
).getMovieName();
ToastUtil
.showToast(movieName
);
}
@Override
public void onItemLongClik(View view
, int position
) {
}
});
}
}
该逻辑代码实现的是当用户打开页面后第一时间从网络加载数据的操作,此时执行的是下拉加载数据的操作,当用户想加载更多数据的话可以上拉加载更多数据。在实现的过程中,本次加载的列表数据是使用RecyclerView和Adapter结合来实现数据的渲染和填充的,所以在实现的过程中如果是下拉刷新数据的时候要把原先的数据集合list清空掉再重新加载数据,如果是上拉加载更多数据的话无需清除掉原先的list数据,只需使用Adapter中自带的notifyItemRangeInserted方法和notifyItemRangeChanged方法来插入数据和刷新界面就可以了。
界面运行效果图如下:
apk安装包下载体验地址:
可以扫描以下二维码进行下载安装,或者点击以下链接 https://fir.im/pullrefresh 进行下载安装体验。
———————— The end ————————
码字不易,如果您觉得这篇博客写的比较好的话,可以赞赏一杯咖啡吧~~
Demo程序源码下载地址一(GitHub) Demo程序源码下载地址二(码云)