Android之RecyclerView輕松實現(xiàn)下拉刷新和加載更多示例
今天研究了下RecyclerView的滑動事件,特別是下拉刷新和加載更多事件,在現(xiàn)在幾乎所有的APP顯示數(shù)據(jù)列表時都用到了。自定義RecyclerView下拉刷新和加載更多聽上去很復(fù)雜,實際上并不難,只要是對滑動事件的監(jiān)聽和處理。
一、自定義RecyclerView實現(xiàn)下拉刷新和加載更多
1、如何判斷RecyclerView是在上滑還是下滑
在RecyclerView的OnScrollListener滑動事件監(jiān)聽中有個好用的方法,就是onScrolled(RecyclerView recyclerView, int dx, int dy),其中根據(jù)dx的值的正負就可以判斷是在左滑還是右滑,而根據(jù)dy的值就可以判斷是在上滑還是下滑。
//上滑
if(dy>0){
//相應(yīng)操作代碼
}
//下滑
else if(dy<0){
//相應(yīng)操作代碼
}
2、如何判斷是否滑到了頂部或者底部
同樣在RecyclerView的OnScrollListener滑動事件監(jiān)聽中onScrolled(RecyclerView recyclerView, int dx, int dy)方法中處理,根據(jù)canScrollVertically(int direction)來進行判斷。
//是否滑到底部
if(!recyclerView.canScrollVertically(1)){
//相應(yīng)處理操作
}
//是否滑到頂部
if(!recyclerView.canScrollVertically(-1)){
//相應(yīng)處理操作
}
3、自定義RecyclerView
知道了滑動事件的判斷和處理,就可以很輕松得實現(xiàn)下拉刷新和加載更多了。
import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
/**
* Package:com.liuting.library
* author:liuting
* Date:2017/2/14
* Desc:自定義RecycleView,下拉刷新以及上拉加載更多
*/
public class RefreshLoadMoreRecycleView extends RecyclerView {
private Boolean isLoadMore;//是否可以加載更多標(biāo)志
private Boolean isLoadEnd;//加載到最后的標(biāo)志
private Boolean isLoadStart;//頂部的標(biāo)志
private Boolean isRefresh;//是否可以下拉刷新標(biāo)志
private int lastVisibleItem;//最后一項
private IOnScrollListener listener;//事件監(jiān)聽
public RefreshLoadMoreRecycleView(Context context) {
super(context);
init(context);
}
public RefreshLoadMoreRecycleView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
public RefreshLoadMoreRecycleView(Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public void init(Context context) {
isLoadEnd=false;
isLoadStart =true;
this.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
//SCROLL_STATE_DRAGGING 和 SCROLL_STATE_IDLE 兩種效果自己看著來
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
if (isLoadEnd) {
// 判斷是否已加載所有數(shù)據(jù)
if (isLoadMore) {//未加載完所有數(shù)據(jù),加載數(shù)據(jù),并且還原isLoadEnd值為false,重新定位列表底部
if (getListener() != null) {
getListener().onLoadMore();
}
} else {//加載完了所有的數(shù)據(jù)
if(getListener()!=null){
getListener().onLoaded();
}
}
isLoadEnd = false;
} else if (isLoadStart) {
if(isRefresh){
if (getListener() != null) {
getListener().onRefresh();
}
isLoadStart=false;
}
}
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
//上滑
if(dy>0){
//是否滑到底部
if(!recyclerView.canScrollVertically(1)){
isLoadEnd = true;
}else{
isLoadEnd = false;
}
}
//下滑
else if(dy<0){
//是否滑到頂部
if(!recyclerView.canScrollVertically(-1)){
isLoadStart=true;
}else{
isLoadStart=false;
}
}
}
});
}
//監(jiān)聽事件
public interface IOnScrollListener {
void onRefresh();
void onLoadMore();
void onLoaded();
}
public IOnScrollListener getListener() {
return listener;
}
public void setListener(IOnScrollListener listener) {
this.listener = listener;
}
public Boolean getLoadMore() {
return isLoadMore;
}
//設(shè)置是否支持加載更多
public void setLoadMoreEnable(Boolean loadMore) {
isLoadMore = loadMore;
}
public Boolean getRefresh() {
return isRefresh;
}
//設(shè)置是否支持下拉刷新
public void setRefreshEnable(Boolean refresh) {
isRefresh = refresh;
}
}
二、實際用例
已經(jīng)定義好了RecyclerView,下面在Demo中實際使用和處理。
1、定義布局
布局文件很簡單,就是一個RecyclerView
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.liuting.refreshloadmorelistview.MainActivity"> <com.liuting.library.RefreshLoadMoreRecycleView android:id="@+id/main_recycle_view_data" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="none" /> </LinearLayout>
2、定義RecyclerView.Adapter
RecyclerView.Adapter在這里就簡單處理了,列表布局直接使用Android自帶的。
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.List;
/**
* Package:com.liuting.refreshloadmorelistview.adapter
* author:liuting
* Date:2017/2/16
* Desc:列表Adapter
*/
public class RefreshLoadMoreRecycleAdapter extends RecyclerView.Adapter<RefreshLoadMoreRecycleAdapter.ViewHolder> {
private List<String> list;
private Context context;
public RefreshLoadMoreRecycleAdapter(Context context,List<String> list) {
this.context =context;
this.list = list;
}
@Override
public RefreshLoadMoreRecycleAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_expandable_list_item_1, parent, false);
RefreshLoadMoreRecycleAdapter.ViewHolder viewHolder = new RefreshLoadMoreRecycleAdapter.ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.text.setText(list.get(position));
holder.itemView.setTag(position);
}
@Override
public int getItemCount() {
return list.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
private TextView text;
public ViewHolder(View itemView) {
super(itemView);
text=(TextView)itemView.findViewById(android.R.id.text1);
}
}
}
3、在Activity中定義好控件以及數(shù)據(jù)加載操作
實現(xiàn)自定義RecyclerView中的數(shù)據(jù)加載事件監(jiān)聽,刷新、加載更多以及加載完成。
import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.widget.Toast;
import com.liuting.library.RefreshLoadMoreRecycleView;
import com.liuting.refreshloadmorelistview.adapter.RefreshLoadMoreRecycleAdapter;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements RefreshLoadMoreRecycleView.IOnScrollListener{
private RefreshLoadMoreRecycleView recycleView;//下拉刷新RecycleView
private List<String> list;//列表
private RefreshLoadMoreRecycleAdapter adapter;//Adapter
private ProgressDialog dialog;//提示框
private static final int REFRESH_Load=0;//下拉刷新
private static final int MORE_Load=1;//加載更多
private Handler handler =new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case REFRESH_Load:
recycleView.setLoadMoreEnable(true);
dismissDialog();
if(list!=null){
list.clear();
}
loadData();
adapter.notifyDataSetChanged();
break;
case MORE_Load:
recycleView.setLoadMoreEnable(false);
dismissDialog();
loadData();
adapter.notifyDataSetChanged();
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
public void initView(){
dialog = new ProgressDialog(MainActivity.this);
list=new ArrayList<>();
loadData();
recycleView = (RefreshLoadMoreRecycleView)findViewById(R.id.main_recycle_view_data);
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(MainActivity.this);
recycleView.setLayoutManager(linearLayoutManager);
adapter = new RefreshLoadMoreRecycleAdapter(MainActivity.this,list);
recycleView.setAdapter(adapter);
recycleView.setListener(this);
recycleView.setRefreshEnable(true);
recycleView.setLoadMoreEnable(true);
}
/**
* 加載數(shù)據(jù)
*/
public void loadData(){
for(int i=0;i<10;i++ ){
list.add("It is "+i);
}
}
@Override
public void onRefresh() {
showDialog();
new Thread(){
@Override
public void run() {
super.run();
try {
sleep(5000);
handler.sendEmptyMessage(REFRESH_Load);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
@Override
public void onLoadMore() {
showDialog();
new Thread(){
@Override
public void run() {
super.run();
try {
sleep(5000);
handler.sendEmptyMessage(MORE_Load);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
@Override
public void onLoaded() {
Toast.makeText(MainActivity.this,"Loaded all",Toast.LENGTH_SHORT).show();
}
/**
* dismiss dialog
*/
private void dismissDialog(){
if (dialog!=null&&dialog.isShowing()){
dialog.dismiss();
}
}
/**
* show dialog
*/
private void showDialog(){
if (dialog!=null&&!dialog.isShowing()){
dialog.show();
}
}
}
三、最終效果圖

到這里就輕松實現(xiàn)了RecyclerView的下拉刷新和加載更多了。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- android RecyclerView側(cè)滑菜單,滑動刪除,長按拖拽,下拉刷新上拉加載
- Android RecyclerView實現(xiàn)下拉刷新和上拉加載更多
- Android RecyclerView上拉加載和下拉刷新(基礎(chǔ)版)
- Android RecyclerView上拉加載和下拉刷新
- RecyclerView下拉刷新上拉加載
- Android RecyclerView下拉刷新和上拉加載更多
- Android使用recyclerview打造真正的下拉刷新上拉加載效果
- Android RecyclerView 上拉加載更多及下拉刷新功能的實現(xiàn)方法
- Android RecyclerView實現(xiàn)下拉刷新和上拉加載
- XRecyclerView實現(xiàn)下拉刷新、滾動到底部加載更多等功能
相關(guān)文章
android高仿微信表情輸入與鍵盤輸入代碼(詳細實現(xiàn)分析)
表情與鍵盤的切換輸入大部分IM都會需要到,本篇文章主要介紹了android高仿微信表情輸入與鍵盤輸入,具有一定的參考價值,有興趣的可以了解一下。2016-12-12
Android UI控件之ListView實現(xiàn)圓角效果
這篇文章主要為大家詳細介紹了Android UI控件之ListView實現(xiàn)圓角效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-12-12
使用ViewPager實現(xiàn)高仿launcher左右拖動效果
今天用ViewPager這個類實現(xiàn)了同樣的左右拖動效果,這樣代碼更少,但是效果是一樣的,ViewPager是實現(xiàn)左右兩個屏幕平滑地切換的一個類,它是Google提供的,有需要的朋友可以了解下2013-01-01
Android 設(shè)置主題實現(xiàn)點擊波紋效果的示例
本篇文章主要介紹了Android 設(shè)置主題實現(xiàn)點擊波紋效果的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-11-11
詳解Android_性能優(yōu)化之ViewPager加載成百上千高清大圖oom解決方案
這篇文章主要介紹了詳解Android_性能優(yōu)化之ViewPager加載成百上千高清大圖oom解決方案,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2016-12-12

