SwipeRefreshLayout配合RecyclerView实现下拉刷新和上拉加载更多以及没有数据的显示

http://blog.csdn.net/lovexieyuan520/article/details/50589412(转)

SwipeRefreshLayout配合RecyclerView实现下拉刷新和上拉加载更多以及没有数据的显示

标签: SwipeRefreshLayoutRecyclerViewCardView下拉刷新上拉加载更多
  829人阅读  评论(2)  收藏  举报
  分类:
 
android(70) 

目录(?)[+]

随着android5.0的发布,google还发布了SwipeRefreshLayout,RecyclerView,CardView几个有用的控件,今天我写这篇博客记录下我的使用过程,内容包括正在刷新加载,下拉刷新,上拉加载更多,无数据的提示信息的显示,也希望给这方面有疑惑的一点帮助!!!

首先当然是添加对这些控件的依赖,由于我使用的是Android studio,这个很简单,添加如下的代码在build.gradle下:

[java]  view plain  copy
 
  1. compile 'com.android.support:appcompat-v7:23.1.1'  
  2. compile 'com.android.support:support-v4:23.1.1'  
  3. compile 'com.android.support:recyclerview-v7:23.1.1'  
  4. compile 'com.android.support:cardview-v7:23.1.1'  

目前为止,最新的版本是23.1.1,看到这篇博客的时候,大家的版本可能会更新,大家使用最新的版本就好。

1、下拉刷新

在进入一个新界面的时候需要一个显示正在加载数据的进度条,我们只需要使用如下的代码就可以显示这个进度条:
[java]  view plain  copy
 
  1. mSwipeRefreshLayout.post(new Runnable() {  
  2.   
  3.     @Override  
  4.     public void run() {  
  5.         mSwipeRefreshLayout.setRefreshing(true);  
  6.     }  
  7. });  

大家注意这段代码是写在onCreate方法中的,大家如果直接mSwipeRefreshLayout.setRefreshing(true);写成这样,那么很可能这进度条不显示出来,原因大家请参看 http://www.zhaoyb.cn/swiperefreshlayout%E8%B0%83%E7%94%A8setrefreshingtrue%E4%B8%8D%E6%98%BE%E7%A4%BA%E8%A7%A3%E5%86%B3/,加载完成以后调用mSwipeRefreshLayout.setRefreshing(false);即可取消加载进度条,下拉刷新很简单,界面如下所示:

完整的代码如下:
布局文件activity_main.xml如下:
[html]  view plain  copy
 
  1. xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout  
  3.     xmlns:android="http://schemas.android.com/apk/res/android"  
  4.     xmlns:tools="http://schemas.android.com/tools"  
  5.     android:layout_width="match_parent"  
  6.     android:layout_height="match_parent"  
  7.     tools:context="com.example.recycleviewdemo.MainActivity">  
  8.   
  9.     <android.support.v4.widget.SwipeRefreshLayout  
  10.         android:id="@+id/swiperefreshlayout"  
  11.         android:layout_width="match_parent"  
  12.         android:layout_height="match_parent">  
  13.   
  14.         <android.support.v7.widget.RecyclerView  
  15.             android:id="@+id/recyclerview"  
  16.             android:layout_width="match_parent"  
  17.             android:layout_height="wrap_content"/>  
  18.     android.support.v4.widget.SwipeRefreshLayout>  
  19. RelativeLayout>  

MainActivity.java文件如下:
[java]  view plain  copy
 
  1. import android.support.v4.widget.SwipeRefreshLayout;  
  2. import android.support.v7.app.AppCompatActivity;  
  3. import android.os.Bundle;  
  4. import android.support.v7.widget.LinearLayoutManager;  
  5. import android.support.v7.widget.RecyclerView;  
  6.   
  7. import java.util.ArrayList;  
  8. import java.util.List;  
  9.   
  10. public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener{  
  11.     private SwipeRefreshLayout mSwipeRefreshLayout;  
  12.     private RecyclerView mRecyclerView;  
  13.     private ItemsAdapter mAdapter;  
  14.     private List mData;  
  15.   
  16.     @Override  
  17.     protected void onCreate(Bundle savedInstanceState) {  
  18.         super.onCreate(savedInstanceState);  
  19.         setContentView(R.layout.activity_main);  
  20.   
  21.         mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swiperefreshlayout);  
  22.         mSwipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary, R.color.colorPrimaryDark);  
  23.         mSwipeRefreshLayout.setOnRefreshListener(this);  
  24.         mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);  
  25.         WrapContentLinearLayoutManager layoutManager = new WrapContentLinearLayoutManager(this, LinearLayoutManager.VERTICAL, false){  
  26.             @Override  
  27.             protected int getExtraLayoutSpace(RecyclerView.State state) {  
  28.                 return 6000;  
  29.             }  
  30.         };  
  31.         mRecyclerView.setLayoutManager(layoutManager);  
  32.         //mRecyclerView.addItemDecoration(new DividerDecoration(this));  
  33.         mData = new ArrayList<>();  
  34.         mSwipeRefreshLayout.post(new Runnable() {  
  35.   
  36.             @Override  
  37.             public void run() {  
  38.                 mSwipeRefreshLayout.setRefreshing(true);  
  39.             }  
  40.         });  
  41.         loadData();  
  42.     }  
  43.   
  44.     private void loadData(){  
  45.         new Thread(){  
  46.             @Override  
  47.             public void run() {  
  48.                 super.run();  
  49.                 try {  
  50.                     Thread.sleep(5000);  
  51.                     int index = mData.size();  
  52.                     for(int i=index;i20;i++){  
  53.                         mData.add("第"+i+"个数据");  
  54.                     }  
  55.                     runOnUiThread(new Runnable() {  
  56.                         @Override  
  57.                         public void run() {  
  58.                             setAdapter();  
  59.                             mSwipeRefreshLayout.setRefreshing(false);  
  60.                         }  
  61.                     });  
  62.                 } catch (InterruptedException e) {  
  63.                     e.printStackTrace();  
  64.                 }  
  65.             }  
  66.         }.start();  
  67.     }  
  68.   
  69.     private void setAdapter(){  
  70.         if(mAdapter==null){  
  71.             mAdapter = new ItemsAdapter(this,mData);  
  72.             mRecyclerView.setAdapter(mAdapter);  
  73.         }else{  
  74.             mAdapter.notifyDataSetChanged();  
  75.         }  
  76.     }  
  77.   
  78.     @Override  
  79.     public void onRefresh() {  
  80.         mData.clear();  
  81.         loadData();  
  82.     }  
  83. }  

ItemsAdapter.java文件内容如下:
[java]  view plain  copy
 
  1. import android.content.Context;  
  2. import android.support.v7.widget.RecyclerView;  
  3. import android.view.LayoutInflater;  
  4. import android.view.ViewGroup;  
  5.   
  6. import java.util.List;  
  7.   
  8. /** 
  9.  * Created by Administrator on 2016/1/26. 
  10.  */  
  11. public class ItemsAdapter extends RecyclerView.Adapter {  
  12.     private List mData;  
  13.     private final LayoutInflater mLayoutInflater;  
  14.     private Context mContext;  
  15.   
  16.     public ItemsAdapter(Context context, List data) {  
  17.         this.mContext = context;  
  18.         this.mData = data;  
  19.         this.mLayoutInflater = LayoutInflater.from(mContext);  
  20.     }  
  21.   
  22.     @Override  
  23.     public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
  24.         return new ItemHolder(mLayoutInflater.inflate(R.layout.item_list, parent, false));  
  25.     }  
  26.   
  27.     @Override  
  28.     public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {  
  29.         final String string = mData.get(position);  
  30.         ItemHolder itemHolder = (ItemHolder)holder;  
  31.         itemHolder.mTextView.setText(string);  
  32.     }  
  33.   
  34.     @Override  
  35.     public int getItemCount() {  
  36.         return mData.size();  
  37.     }  
  38. }  

item_list.xml文件如下:
[html]  view plain  copy
 
  1. xml version="1.0" encoding="utf-8"?>  
  2. <android.support.v7.widget.CardView  
  3.     android:id="@+id/cv_item"  
  4.     xmlns:android="http://schemas.android.com/apk/res/android"  
  5.     xmlns:card_view="http://schemas.android.com/apk/res-auto"  
  6.     xmlns:tools="http://schemas.android.com/tools"  
  7.     android:layout_width="match_parent"  
  8.     android:layout_height="wrap_content"  
  9.     android:layout_margin="8dp"  
  10.     android:descendantFocusability="blocksDescendants"  
  11.     card_view:cardCornerRadius="4dp"  
  12.     card_view:cardUseCompatPadding="true">  
  13.   
  14.     <TextView  
  15.         android:id="@+id/item"  
  16.         android:layout_width="wrap_content"  
  17.         android:layout_height="wrap_content"  
  18.         android:layout_margin="20dp"  
  19.         tools:text="item"/>  
  20. android.support.v7.widget.CardView>  

以上是刷新的相关图片和代码。。。

2、上拉加载更多

当我们滚动RecyclerView的时候,去加载更多的数据,同时在RecyclerView的底部显示一个进度条,这个的原理就是在数据集的最后面加上一个null,刷新界面的时候判断,如果是空就显示一个进度条的布局,配合RecycleView的滚动事件,先上图有直观的认识:

主要是在之前的基础上加了个有进度条的布局,还有就是加了滚动的事件,核心代码如下:
[java]  view plain  copy
 
  1. if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) {  
  2.             final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();  
  3.             recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {  
  4.                 @Override  
  5.                 public void onScrolled(RecyclerView recyclerView, int dx, int dy) {  
  6.                     super.onScrolled(recyclerView, dx, dy);  
  7.                     totalItemCount = linearLayoutManager.getItemCount();  
  8.                     lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();  
  9.                     if (!loading && totalItemCount <= (lastVisibleItem + visibleThreshold)) {  
  10.                         // End has been reached  
  11.                         // Do something  
  12.                         if (onLoadMoreListener != null) {  
  13.                             onLoadMoreListener.onLoadMore();  
  14.                         }  
  15.                     }  
  16.                 }  
  17.             });  
  18.         }  

3、当没有数据的时候给提示

效果如下:

原理也一样,就显示一个没有提示的item,没什么好说的。
这SwipeRefreshLayout,RecyclerView,CardView三个控件组合起来,能够实现比较人性化的用户体验。
最后,给出整个demo的下载地址: http://download.csdn.net/detail/lovexieyuan520/9418952,大家有什么问题或者是更好的建议,请给我留言。
还有个问题,就是在使用RecycleView会报IndexOutOfBoundsException: Inconsistency detected,详情请看http://blog.csdn.net/lovexieyuan520/article/details/50537846

你可能感兴趣的:(RecyclerView)