FastDev4Android框架开发RecyclerView完全解析之下拉刷新与上拉加载SwipeRefreshLayout(三十一)

Posted lenkevin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FastDev4Android框架开发RecyclerView完全解析之下拉刷新与上拉加载SwipeRefreshLayout(三十一)相关的知识,希望对你有一定的参考价值。

 转载请标明出处:

http://blog.csdn.net/developer_jiangqq/article/details/49992269

本文出自:【江清清的博客】

 

().前言:   

        【好消息】个人网站已经上线运行,后面博客以及技术干货等精彩文章会同步更新,请大家关注收藏:http://www.lcode.org 

      话说RecyclerView已经面市很久,也在很多应用中得到广泛的使用,在整个开发者圈子里面也拥有很不错的口碑,那说明RecyclerView拥有比ListView,GridView之类控件有很多的优点,例如:数据绑定,Item View创建,View的回收以及重用等机制。前三三篇文章已经贡呢更新了以下三个部分:

  1. RecyclerView控件的基本使用,包括基础,进阶,高级部分,动画之类(点击进入)
  2. RecyclerView控件的实战实例(点击进入)
  3. RecyclerView控件集合AA(android Annotations)注入框架实例(点击进入)

         本来这个专题不打算更新,不过前两天看到各位童鞋还是挺积极的评论到,希望可以更新RecyclerView加入下拉刷新和上拉加载更多的功能。正好昨天周末,所以我这边也就实现了这样的功能,今天更新一下。具体代码已经上传到下面的项目中,欢迎各位去star和fork一下。

         FastDev4Android框架项目地址:https://github.com/jiangqqlmj/FastDev4Android

         RecyclerView实现的列表,默认情况下面是不带下拉刷新和上拉记载更多效果的,但是我在我们的实际项目当中,为了提高用户体验,这种效果一般都需要实现,在我以前的博客中已经重写了ListView(Android 列表下拉刷新组件PullToRefreshListView使用)实现上拉刷新和上拉加载更多效果。现在我们已经学会了ListView,GridView的替代品RecyclerView的基本使用方法,那么必不可少的也需要实现上拉刷新和上拉加载更多的效果了。今天我们会通过两种方式来实现,具体会采用Android的另一控件SwipeRefreshLayout

().SwipeRefreshLayout介绍:

         SwipeRefrshLayoutGoogle官方更新的一个Widget,可以实现下拉刷新的效果。该控件集成自ViewGroup在support-v4兼容包下,不过我们需要升级supportlibrary的版本到19.1以上。基本使用的方法如下:

  • setOnRefreshListener(OnRefreshListener):添加下拉刷新监听器
  • setRefreshing(boolean):显示或者隐藏刷新进度条
  • isRefreshing():检查是否处于刷新状态
  • setColorSchemeResources():设置进度条的颜色主题,最多设置四种,以前的setColorScheme()方法已经弃用了。

     具体使用效果下面我们会看到。

().RecyclerView+SwpieRefreshLayout实现下拉刷新效果:

       1.SwipeRefreshLayout本身自带下拉刷新的效果,那么我们可以选择在RecyclerView布局外部嵌套一层SwipeRefreshLayout布局即可,具体布局文件如下:

 

[html] view plain copy
  1. <?xmlversionxmlversion="1.0" encoding="utf-8"?>  
  2. <LinearLayoutxmlns:androidLinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"android:layout_width="match_parent"  
  4.    android:layout_height="match_parent">  
  5.     <includelayoutincludelayout="@layout/common_top_bar_layout"/>  
  6.    <android.support.v4.widget.SwipeRefreshLayout  
  7.        android:id="@+id/demo_swiperefreshlayout"  
  8.        android:layout_width="fill_parent"  
  9.        android:layout_height="fill_parent"  
  10.         android:scrollbars="vertical"  
  11.         >  
  12.        <android.support.v7.widget.RecyclerView  
  13.            android:id="@+id/demo_recycler"  
  14.            android:layout_width="fill_parent"  
  15.            android:layout_height="fill_parent"  
  16.            ></android.support.v7.widget.RecyclerView>  
  17.    </android.support.v4.widget.SwipeRefreshLayout>  
  18. </LinearLayout>  

 

      2.接着在Activity中获取SwipeRefreshLayout控件并且设置OnRefreshListener监听器,同时实现里边的onRefresh()方法,在该方法中进行网络请求最新数据,然后刷新RecyclerView列表同时设置SwipeRefreshLayout的进度Bar的隐藏或者显示效果。具体代码如下:

 

[java] view plain copy
  1. demo_swiperefreshlayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {  
  2.             @Override  
  3.             public void onRefresh() {  
  4.                 Log.d("zttjiangqq","invoke onRefresh...");  
  5.                 new Handler().postDelayed(newRunnable() {  
  6.                     @Override  
  7.                     public void run() {  
  8.                         List<String> newDatas = new ArrayList<String>();  
  9.                         for (int i = 0; i <5; i++) {  
  10.                             int index = i + 1;  
  11.                            newDatas.add("new item" + index);  
  12.                         }  
  13.                        adapter.addItem(newDatas);  
  14.                        demo_swiperefreshlayout.setRefreshing(false);  
  15.                        Toast.makeText(RecyclerRefreshActivity.this, "更新了五条数据...", Toast.LENGTH_SHORT).show();  
  16.                     }  
  17.                 }, 5000);  
  18.             }  
  19.         });  

 

   3.除此之外我们也来看一下AdapterActivity中的其他代码,也方便各位童鞋查看。

 

[java] view plain copy
  1. RecyclerRefreshActivity.java  
  2. public class RecyclerRefreshActivity extends BaseActivity {  
  3.     private LinearLayout top_bar_linear_back;  
  4.     private TextView top_bar_title;  
  5.     private SwipeRefreshLayout demo_swiperefreshlayout;  
  6.     private RecyclerView demo_recycler;  
  7.     private RefreshRecyclerAdapter adapter;  
  8.     private LinearLayoutManager linearLayoutManager;  
  9.     private int lastVisibleItem;  
  10.     @Override  
  11.     protected void onCreate(BundlesavedInstanceState) {  
  12.         super.onCreate(savedInstanceState);  
  13.        setContentView(R.layout.recycler_refresh_layout);  
  14.        top_bar_linear_back=(LinearLayout)this.findViewById(R.id.top_bar_linear_back);  
  15.        top_bar_linear_back.setOnClickListener(new CustomOnClickListener());  
  16.        top_bar_title=(TextView)this.findViewById(R.id.top_bar_title);  
  17.        top_bar_title.setText("RecyclerView下拉刷新,下拉加载更多...");  
  18.        demo_swiperefreshlayout=(SwipeRefreshLayout)this.findViewById(R.id.demo_swiperefreshlayout);  
  19.        demo_recycler=(RecyclerView)this.findViewById(R.id.demo_recycler);  
  20.         //设置刷新时动画的颜色,可以设置4个  
  21.        demo_swiperefreshlayout.setProgressBackgroundColorSchemeResource(android.R.color.white);  
  22.        demo_swiperefreshlayout.setColorSchemeResources(android.R.color.holo_blue_light,  
  23.                 android.R.color.holo_red_light,android.R.color.holo_orange_light,  
  24.                android.R.color.holo_green_light);  
  25.        demo_swiperefreshlayout.setProgressViewOffset(false, 0, (int) TypedValue  
  26.                .applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, getResources()  
  27.                         .getDisplayMetrics()));  
  28.         linearLayoutManager=new LinearLayoutManager(this);  
  29.        linearLayoutManager.setOrientation(OrientationHelper.VERTICAL);  
  30.        demo_recycler.setLayoutManager(linearLayoutManager);  
  31.         //添加分隔线  
  32.         demo_recycler.addItemDecoration(new AdvanceDecoration(this, OrientationHelper.VERTICAL));  
  33.         demo_recycler.setAdapter(adapter = new RefreshRecyclerAdapter(this));  
  34.        demo_swiperefreshlayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {  
  35.             @Override  
  36.             public void onRefresh() {  
  37.                 Log.d("zttjiangqq","invoke onRefresh...");  
  38.                 new Handler().postDelayed(newRunnable() {  
  39.                     @Override  
  40.                     public void run() {  
  41.                         List<String> newDatas = new ArrayList<String>();  
  42.                         for (int i = 0; i <5; i++) {  
  43.                             int index = i + 1;  
  44.                            newDatas.add("new item" + index);  
  45.                         }  
  46.                        adapter.addItem(newDatas);  
  47.                        demo_swiperefreshlayout.setRefreshing(false);  
  48.                        Toast.makeText(RecyclerRefreshActivity.this, "更新了五条数据...", Toast.LENGTH_SHORT).show();  
  49.                     }  
  50.                 }, 5000);  
  51.             }  
  52.         });  
  53.           class CustomOnClickListenerimplements View.OnClickListener{  
  54.         @Override  
  55.         public void onClick(View v) {  
  56.            RecyclerRefreshActivity.this.finish();  
  57.         }  
  58.     }  
  59. }  

 

 

[java] view plain copy
  1. RefreshRecyclerAdapter.java  
  2. public class RefreshRecyclerAdapter extends RecyclerView.Adapter<RefreshRecyclerAdapter.ViewHolder>{  
  3.     private LayoutInflater mInflater;  
  4.     private List<String> mTitles=null;  
  5.     public RefreshRecyclerAdapter(Context context){  
  6.        this.mInflater=LayoutInflater.from(context);  
  7.         this.mTitles=new ArrayList<String>();  
  8.         for (int i=0;i<20;i++){  
  9.             int index=i+1;  
  10.            mTitles.add("item"+index);  
  11.         }  
  12.     }  
  13.     /** 
  14.      * item显示类型 
  15.      * @param parent 
  16.      * @param viewType 
  17.      * @return 
  18.      */  
  19.     @Override  
  20.     public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
  21.         final Viewview=mInflater.inflate(R.layout.item_recycler_layout,parent,false);  
  22.         //这边可以做一些属性设置,甚至事件监听绑定  
  23.         //view.setBackgroundColor(Color.RED);  
  24.         ViewHolder viewHolder=new ViewHolder(view);  
  25.    
  26.         return viewHolder;  
  27.     }  
  28.    
  29.     /** 
  30.      * 数据的绑定显示 
  31.      * @param holder 
  32.      * @param position 
  33.      */  
  34.     @Override  
  35.     public void onBindViewHolder(ViewHolder holder, int position) {  
  36.        holder.item_tv.setText(mTitles.get(position));  
  37.         holder.itemView.setTag(position);  
  38.     }  
  39.     @Override  
  40.     public int getItemCount() {  
  41.         return mTitles.size();  
  42.     }  
  43.    
  44.     //自定义的ViewHolder,持有每个Item的的所有界面元素  
  45.     public static class ViewHolder extends RecyclerView.ViewHolder {  
  46.         public TextView item_tv;  
  47.         public ViewHolder(View view){  
  48.             super(view);  
  49.             item_tv = (TextView)view.findViewById(R.id.item_tv);  
  50.         }  
  51.     }  
  52.    
  53.     //添加数据  
  54.     public void addItem(List<String> newDatas) {  
  55.         //mTitles.add(position, data);  
  56.         //notifyItemInserted(position);  
  57.         newDatas.addAll(mTitles);  
  58.         mTitles.removeAll(mTitles);  
  59.         mTitles.addAll(newDatas);  
  60.         notifyDataSetChanged();  
  61.     }  
  62.    
  63.     public void addMoreItem(List<String> newDatas) {  
  64.         mTitles.addAll(newDatas);  
  65.         notifyDataSetChanged();  
  66.     }  
  67. }  

 

以上重要地方的注释已经加上去了。

5.运行效果如下:

技术分享

().RecyclerView设置滚动事件加入上拉加载更多功能

         下面我们再来看RecyclerView和相关类的一些特性,

         LayoutManger给我们提供了以下几个方法来让开发者方便的获取到屏幕上面的顶部item和顶部item相关的信息:

  • findFirstVisibleItemPosition()
  • findFirstCompletlyVisibleItemPosition()
  • findLastVisibleItemPosition()
  • findLastCompletlyVisibleItemPosition()

 同时通过Recycler.AdaptergetItemCount()方法可以轻松获取到RecyclerView列表中Item View的个数。

那么下面我们通过监听滑动(滚动)事件,然后在里边判断是否已经滑动到最底部来加载更多的数据,使用方法如下:

 

[java] view plain copy
  1. //RecyclerView滑动监听  
  2.        demo_recycler.setOnScrollListener(new RecyclerView.OnScrollListener() {  
  3.            @Override  
  4.            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {  
  5.               super.onScrollStateChanged(recyclerView, newState);  
  6.                if (newState ==RecyclerView.SCROLL_STATE_IDLE && lastVisibleItem + 1 ==adapter.getItemCount()) {  
  7.                    new Handler().postDelayed(new Runnable() {  
  8.                        @Override  
  9.                        public void run() {  
  10.                            List<String> newDatas = new ArrayList<String>();  
  11.                            for (int i = 0; i< 5; i++) {  
  12.                                int index = i +1;  
  13.                               newDatas.add("more item" + index);  
  14.                            }  
  15.                           adapter.addMoreItem(newDatas);  
  16.                        }  
  17.                    },1000);  
  18.                }  
  19.            }  
  20.            @Override  
  21.            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {  
  22.                super.onScrolled(recyclerView,dx, dy);  
  23.                lastVisibleItem =linearLayoutManager.findLastVisibleItemPosition();  
  24.            }  
  25.        });  

 

运行效果如下:

技术分享

().升级RecyclerView加入FootView实现上拉加载

         上面我们虽然已经实现了上拉加载更多的效果,但是还比较丑陋,最起码要让用户知道确实在上拉加载的过程吧,例如加载一个底部的进度布局。这样一想,那么我们就按照ListView方式addFootView()呗,不过很可惜的是RecyclerView没有给我们提供addFootView()方法,那该怎么样办呢?我们来看RecyclerView.Apapter类:

我们要实现一个自定义Adapter一定需要实现onCreateViewHolder(ViewGroup paren,int viewType)方法,注意看方法中的第二个参数viewType,是不是想到布局类型了,也就是说该也支持多套布局显示的,那么查看基类中的所有方法如下:

技术分享

上面有一个方法getItemType(),这个就和ListView的Adapter的实现差不多了,那么我们这边可以使用多套布局给RecyclerView加入一个FootView布局即可。RefreshFootAdapter.java具体实现流程如下:

1.加入布局状态标志-用来判断此时加载是普通Item还是foot view:

   private static final int TYPE_ITEM =0;  //普通Item View

   private static final intTYPE_FOOTER = 1;  //顶部FootView

2.重写getItemCount()方法,返回的Item数量在数据的基础上面+1,增加一项FootView布局项

 

[java] view plain copy
  1. public intgetItemCount() {  
  2.      return mTitles.size()+1;  
  3.  }  

 

3.重写getItemViewType方法来判断返回加载的布局的类型

 

[java] view plain copy
  1. public int getItemViewType(int position) {  
  2.   // 最后一个item设置为footerView  
  3.   if (position + 1 == getItemCount()) {  
  4.               return TYPE_FOOTER;  
  5.           } else {  
  6.               return TYPE_ITEM;  
  7.           }  
  8.       }  

 

4.接着onCreateViewHolder(ViewGroup parent,int viewType)加载布局的时候根据viewType的类型来选择指定的布局创建,返回即可:

 

[java] view plain copy
  1. public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
  2.         //进行判断显示类型,来创建返回不同的View  
  3.         if(viewType==TYPE_ITEM){  
  4.             Viewview=mInflater.inflate(R.layout.item_recycler_layout,parent,false);  
  5.             //这边可以做一些属性设置,甚至事件监听绑定  
  6.            //view.setBackgroundColor(Color.RED);  
  7.             ItemViewHolder itemViewHolder=new ItemViewHolder(view);  
  8.             return itemViewHolder;  
  9.         }else if(viewType==TYPE_FOOTER){  
  10.             Viewfoot_view=mInflater.inflate(R.layout.recycler_load_more_layout,parent,false);  
  11.             //这边可以做一些属性设置,甚至事件监听绑定  
  12.            //view.setBackgroundColor(Color.RED);  
  13.             FootViewHolder footViewHolder=new FootViewHolder(foot_view);  
  14.             return footViewHolder;  
  15.         }  
  16.        return null;  
  17.     }  

 

5.最后进行判断数据的时候(onBindViewHolder),判断holder的类型来进行判定数据即可.

 

[java] view plain copy
  1. public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {  
  2.        if(holder instanceof ItemViewHolder) {  
  3.           ((ItemViewHolder)holder).item_tv.setText(mTitles.get(position));  
  4.            holder.itemView.setTag(position);  
  5.        }else if(holder instanceof FootViewHolder){  
  6.            FootViewHolderfootViewHolder=(FootViewHolder)holder;  
  7.            switch (load_more_status){  
  8.                case PULLUP_LOAD_MORE:  
  9.                   footViewHolder.foot_view_item_tv.setText("上拉加载更多...");  
  10.                    break;  
  11.                case LOADING_MORE:  
  12.                   footViewHolder.foot_view_item_tv.setText("正在加载更多数据...");  
  13.                    break;  
  14.            }  
  15.        }  
  16.    }  
6.整个RefreshFootAdapter完整代码如下:

 

 

[java] view plain copy
  1. packagecom.chinaztt.fda.adapter;  
  2. public class RefreshFootAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{  
  3.     //上拉加载更多  
  4.     public static final int  PULLUP_LOAD_MORE=0;  
  5.     //正在加载中  
  6.     public static final int  LOADING_MORE=1;  
  7.     //上拉加载更多状态-默认为0  
  8.     private int load_more_status=0;  
  9.     private LayoutInflater mInflater;  
  10.     private List<String> mTitles=null;  
  11.     private static final intTYPE_ITEM = 0;  //普通Item View  
  12.     private static final intTYPE_FOOTER = 1;  //顶部FootView  
  13.     public RefreshFootAdapter(Context context){  
  14.        this.mInflater=LayoutInflater.from(context);  
  15.         this.mTitles=new ArrayList<String>();  
  16.         for (int i=0;i<20;i++){  
  17.             int index=i+1;  
  18.            mTitles.add("item"+index);  
  19.         }  
  20.     }  
  21.     /** 
  22.      * item显示类型 
  23.      * @param parent 
  24.      * @param viewType 
  25.      * @return 
  26.      */  
  27.     public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
  28.         //进行判断显示类型,来创建返回不同的View  
  29.         if(viewType==TYPE_ITEM){  
  30.             Viewview=mInflater.inflate(R.layout.item_recycler_layout,parent,false);  
  31.             //这边可以做一些属性设置,甚至事件监听绑定  
  32.            //view.setBackgroundColor(Color.RED);  
  33.             ItemViewHolder itemViewHolder=new ItemViewHolder(view);  
  34.             return itemViewHolder;  
  35.         }else if(viewType==TYPE_FOOTER){  
  36.             Viewfoot_view=mInflater.inflate(R.layout.recycler_load_more_layout,parent,false);  
  37.             //这边可以做一些属性设置,甚至事件监听绑定  
  38.            //view.setBackgroundColor(Color.RED);  
  39.             FootViewHolder footViewHolder=new FootViewHolder(foot_view);  
  40.             return footViewHolder;  
  41.         }  
  42.        return null;  
  43.     }  
  44.    
  45.     /** 
  46.      * 数据的绑定显示 
  47.      * @param holder 
  48.      * @param position 
  49.      */  
  50.     public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {  
  51.         if(holder instanceof ItemViewHolder) {  
  52.            ((ItemViewHolder)holder).item_tv.setText(mTitles.get(position));  
  53.             holder.itemView.setTag(position);  
  54.         }else if(holder instanceof FootViewHolder){  
  55.             FootViewHolder footViewHolder=(FootViewHolder)holder;  
  56.             switch (load_more_status){  
  57.                 case PULLUP_LOAD_MORE:  
  58.                    footViewHolder.foot_view_item_tv.setText("上拉加载更多...");  
  59.                     break;  
  60.                 case LOADING_MORE:  
  61.                    footViewHolder.foot_view_item_tv.setText("正在加载更多数据...");  
  62.                     break;  
  63.             }  
  64.         }  
  65.     }  
  66.    
  67.     /** 
  68.      * 进行判断是普通Item视图还是FootView视图 
  69.      * @param position 
  70.      * @return 
  71.      */  
  72.     @Override  
  73.     public int getItemViewType(int position) {  
  74.     // 最后一个item设置为footerView  
  75.     if (position + 1 == getItemCount()) {  
  76.                 return TYPE_FOOTER;  
  77.             } else {  
  78.                 return TYPE_ITEM;  
  79.             }  
  80.         }  
  81.     @Override  
  82.     public int getItemCount() {  
  83.         return mTitles.size()+1;  
  84.     }  
  85.     //自定义的ViewHolder,持有每个Item的的所有界面元素  
  86.     public static class ItemViewHolder extends RecyclerView.ViewHolder {  
  87.         public TextView item_tv;  
  88.         public ItemViewHolder(View view){  
  89.             super(view);  
  90.             item_tv = (TextView)view.findViewById(R.id.item_tv);  
  91.         }  
  92.     }  
  93.     /** 
  94.      * 底部FootView布局 
  95.      */  
  96.     public static class FootViewHolder extends  RecyclerView.ViewHolder{  
  97.         private TextView foot_view_item_tv;  
  98.         public FootViewHolder(View view) {  
  99.             super(view);  
  100.            foot_view_item_tv=(TextView)view.findViewById(R.id.foot_view_item_tv);  
  101.         }  
  102.     }  
  103.    
  104.     //添加数据  
  105.     public void addItem(List<String> newDatas) {  
  106.         //mTitles.add(position, data);  
  107.         //notifyItemInserted(position);  
  108.         newDatas.addAll(mTitles);  
  109.         mTitles.removeAll(mTitles);  
  110.         mTitles.addAll(newDatas);  
  111.         notifyDataSetChanged();  
  112.     }  
  113.    
  114.     public void addMoreItem(List<String> newDatas) {  
  115.         mTitles.addAll(newDatas);  
  116.         notifyDataSetChanged();  
  117.     }  
  118.    
  119.     /** 
  120.      * //上拉加载更多 
  121.      * PULLUP_LOAD_MORE=0; 
  122.      * //正在加载中 
  123.      * LOADING_MORE=1; 
  124.      * //加载完成已经没有更多数据了 
  125.      * NO_MORE_DATA=2; 
  126.      * @param status 
  127.      */  
  128.     public void changeMoreStatus(int status){  
  129.         load_more_status=status;  
  130.         notifyDataSetChanged();  
  131.     }  
  132. }  

 

同时该Adaper中我还定义一个changeMoreStatus()方法和两个字符串常量可以来进行修改FootView中字符串提醒文本的。

7.整体Activity中还是设置监听RecyclerView的滚动事件.代码和第一个例子差不多,不过RecyclerView需要设置这边的Adapter,demo_recycler.setAdapter(adapter= new RefreshFootAdapter(this));

 

[java] view plain copy
  1. demo_recycler.setOnScrollListener(new RecyclerView.OnScrollListener() {  
  2.             @Override  
  3.             public void onScrollStateChanged(RecyclerView recyclerView, int newState) {  
  4.                super.onScrollStateChanged(recyclerView, newState);  
  5.                 if (newState ==RecyclerView.SCROLL_STATE_IDLE && lastVisibleItem + 1 ==adapter.getItemCount()) {  
  6.                    adapter.changeMoreStatus(RefreshFootAdapter.LOADING_MORE);  
  7.                     newHandler().postDelayed(new Runnable() {  
  8.                         @Override  
  9.                         public void run() {  
  10.                             List<String> newDatas = new ArrayList<String>();  
  11.                             for (int i = 0; i< 5; i++) {  
  12.                                 int index = i +1;  
  13.                                newDatas.add("more item" + index);  
  14.                             }  
  15.                            adapter.addMoreItem(newDatas);  
  16.                            adapter.changeMoreStatus(RefreshFootAdapter.PULLUP_LOAD_MORE);  
  17.                         }  
  18.                     }, 2500);  
  19.                 }  
  20.             }  
  21.             @Override  
  22.             public void onScrolled(RecyclerView recyclerView, int dx, int dy) {  
  23.                 super.onScrolled(recyclerView,dx, dy);  
  24.                 lastVisibleItem =linearLayoutManager.findLastVisibleItemPosition();  
  25.             }  
  26.         });  

 

查看代码之后,大家肯定也发现在onScrollStateChanged()方法中,Adapter.addMoreItem()和Adapter.changeMoreStatus()方法内部都调用了notifyDataSetChanged()方法,也就是说这边刷新了两次,针对这个问题,大家可以把第二个方法放入到addMoreItem()内部去,调用一次刷新操作接口。同时也可以自己按照实际需求进行优化。

8.运行效果如下:

技术分享

().最后总结

           今天我们通过SwipeRefreshLayoutRecyclerView结合以及改造Adapter方式实现了RecyclerView的下拉刷新和上拉加载更多的效果。

           本次具体实例注释过的全部代码已经上传到FastDev4Android项目中了。同时欢迎大家去Github站点进行clone或者下载浏览:

https://github.com/jiangqqlmj/FastDev4Android 同时欢迎大家starfork整个开源快速开发框架项目~

 

           本人录制AA(Android Annotations)注入框架的视频教程已经上线了,欢迎大家前往观看。http://www.cniao5.com/course/10074

       

尊重原创,转载请注明:From Sky丶清(http://blog.csdn.net/developer_jiangqq) 侵权必究!

关注我的订阅号,每天分享移动开发技术(Android/ios),项目管理以及博客文章!

技术分享

关注我的微博,可以获得更多精彩内容

技术分享

 

 

 
28
 
0
 

 

 
查看评论
16楼 L_Fork2017-09-05 17:46发表  [回复]
技术分享
改为 mTitles.addAll(0, newDatas);
15楼 帅哥镶金牙2017-08-15 21:18发表  [回复]
技术分享
你给的这个github地址哪里找得到你这项目的代码啊,真的找得人都心烦意乱
14楼 chemin5202017-07-20 17:35发表  [回复]
技术分享
研究了一下,解决了不满一页footview会出现的问题,
首先多定义一个标记LOADING_END ,默认是0:
public static final int PULLUP_LOAD_MORE = 2;
public static final int LOADING_MORE = 1;
//没有加载的时候
public static final int LOADING_END = 0;
把footview的根布局find出来,默认是gone,贴上改变的代码
switch (load_more_status) {
case PULLUP_LOAD_MORE:
footViewHolderfoot_view_item_containersetVisibility(ViewVISIBLE);
footViewHolderfoot_view_item_tvsetText(&quot;上拉加载更多...&quot;);
break;
case LOADING_MORE:
footViewHolderfoot_view_item_containersetVisibility(ViewVISIBLE);
footViewHolderfoot_view_item_tv.setText(&quot;正在加载更多数据...&quot;);
break;
case LOADING_END:
footViewHolderfoot_view_item_containesetVisibility(ViewGONE);
break;
}
数据加载完成后调用adapterchangeMoreStatus(RefreshFootAdapterLOADING_END);
就OK了,希望对大家有帮助~(PS.代码中去掉了&quot;.&quot;)
Re: black_and_blue2017-08-28 13:44发表  [回复]
技术分享
回复chemin520:看样子还不错.
13楼 chemin5202017-07-20 17:33发表  [回复]
技术分享
研究了一下,解决了不满一页footview会出现的问题,
首先多定义一个标记LOADING_END ,默认是0:
public static final int PULLUP_LOAD_MORE = 2;
public static final int LOADING_MORE = 1;
//没有加载的时候
public static final int LOADING_END = 0;
把footview的根布局find出来,默认是gone,贴上改变的代码
switch (load_more_status) {
case PULLUP_LOAD_MORE:
footViewHolderfoot_view_item_containersetVisibility(View.VISIBLE);
footViewHolderfoot_view_item_tvsetText(&quot;上拉加载更多...&quot;);
break;
case LOADING_MORE:
footViewHolderfoot_view_item_containersetVisibility(View.VISIBLE);
footViewHolder.foot_view_item_tv.setText(&quot;正在加载更多数据...&quot;);
break;
case LOADING_END:
footViewHolderfoot_view_item_containe.setVisibility(View.GONE);
break;
}
数据加载完成后调用adapterchangeMoreStatus(RefreshFootAdapterLOADING_END);
就OK了,希望对大家有帮助~(PS.由于被误认为是链接,所以把.去掉了)
12楼 greenfly2017-05-18 11:40发表  [回复]
技术分享
写的不错,不过有些细节对于新手来说会比较麻烦,不满一页的时候一直显示加载,到最后一页还显示加载,用户体验会比较差,网上搜索也没有结果,花点时间调试了下,用下面代码可以实现不满一页的时候隐藏footview,和下拉到最后一页的时候,不再显示footview

@Override
public int getItemViewType(int position) {
// 最后一个item设置为footerView
if (position + 1 == getItemCount()) {
if(totalPage>1&&getItemCount()<totalRecord){
return TYPE_FOOTER;
}else{
return TYPE_ITEM;
}
//return TYPE_FOOTER;
} else {
return TYPE_ITEM;
}
}
@Override
public int getItemCount() {
return mDatas.size();
}

还有个思路就是让footview显示2秒自动隐藏,这个方法会比较方便些。
Re: 小神的烦恼2017-06-13 16:02发表  [回复]
技术分享
回复greenfly:if(totalPage>1&&getItemCount()<totalRecord)中totalPage是页数吗?totalRecord是什么?
Re: qq_388631902017-05-20 17:30发表  [回复]
技术分享
回复greenfly:您写的totalPage是指什么?totalRecord又是指什么呢?能详细贴出来吗
11楼 greenfly2017-05-15 17:14发表  [回复]
技术分享
thank you.
10楼 haohao123nana2016-11-25 17:52发表  [回复]
技术分享
不错不错,学习了
9楼 雪谷歧路2016-08-25 16:56发表  [回复]
技术分享
请问加载完成之后怎么隐藏加载更多的footer啊,我发现很多人都没写一点,自己也尝试很久都没用,望解答
8楼 chaoxionghuai2016-08-05 16:08发表  [回复]
技术分享
楼主 ,当第一页数据不满屏 时,怎样隐藏footer,有这方面的处理思路吗,貌似这个问题挺常见的
7楼 qq_5272358902016-05-02 18:31发表  [回复]
技术分享
不适合新手,但还是谢谢
6楼 SnowWitch2016-02-22 09:23发表  [回复]
技术分享
博主,如果数据不足一页,那个footview也会显示出来,该如何隐藏呢?希望博主指点一下。
Re: qq_333412182017-02-08 15:05发表  [回复]
技术分享
回复SnowWitch:要动态设置adapter的getItemCount的返回个数,既然有上拉加载更多,那就是分页请求,请求接口的时候肯定要传一个数值,如果返回的数据集合小于传入的这个数值,那就说明服务器没有更多的数据了,getItemCount的返回个数就不需要+1
@Override  
public int getItemCount() {  
if(mTitles.size() < 分页请求的数值)
{
return mTitles.size()
}else
{
return mTitles.size()+1;  
}
}
Re: SnowWitch2017-02-10 22:32发表  [回复]
技术分享
回复qq_33341218:嗯嗯,谢谢亲
5楼 qq1686100102016-01-13 21:14发表  [回复]
技术分享
博主是选择如何隐藏footerView的,上面的代码好像没有啊?
4楼 awenshixiaocao2016-01-07 16:12发表  [回复]
技术分享
好厉害的demo,太感谢了,学了很多东西
Re: 江清清2016-01-07 16:15发表  [回复]
技术分享
回复awenshixiaocao:感谢支持关注一下,不断学习吧,
3楼 IT_Transformers2015-11-27 17:07发表  [回复]
技术分享
你有试过数据不足一屏的时候 上拉加载吗?
Re: 江清清2015-11-27 17:10发表  [回复]
技术分享
回复IT_Transformers:如果是这种情况会有其他的方式处理
Re: IT_Transformers2015-11-27 17:13发表  [回复]
技术分享
回复江清清:能提供一个思路吗?我最近在学习recyclerview
2楼 zhiyou13802015-11-26 13:31发表  [回复]
技术分享
不错不错哦~!!
Re: 江清清2015-11-26 13:42发表  [回复]
技术分享
回复zhiyou1380:感谢支持,后面也希望可以写出质量更高的文章 和大家一起分享
1楼 stupid_boy11032015-11-23 14:45发表  [回复]
技术分享
很不错,收藏了先
Re: 江清清2015-11-23 14:50发表  [回复]
技术分享
回复stupid_boy1103:感谢支持。
 
发表评论
  • 用 户 名:
  • Leaning_wk
  • 评论内容:
  • 技术分享
      
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
 
 
 
 
    个人资料
 
 
    • 访问:1104090次
    • 积分:12921
    • 等级: 技术分享
    • 排名:第1072名
    • 原创:215篇
    • 转载:5篇
    • 译文:1篇
    • 评论:590条
    联系方式
技术分享
技术分享
技术分享

    博客专栏
技术分享 React Native学习指南

文章:24篇

阅读:267557
技术分享 FastDev4Android

文章:38篇

阅读:228684
技术分享 AndroidAnnotations详解

文章:11篇

阅读:23097
技术分享 Android进阶与专题

文章:8篇

阅读:29586
技术分享 RoboGuice注入框架

文章:14篇

阅读:25891
技术分享 【IOS入门与进阶】

文章:13篇

阅读:47984
技术分享 【Objective-C入门与进阶】

文章:24篇

阅读:66720
    文章存档
    最新评论
    底部悬停
技术分享
 
 
 















































































以上是关于FastDev4Android框架开发RecyclerView完全解析之下拉刷新与上拉加载SwipeRefreshLayout(三十一)的主要内容,如果未能解决你的问题,请参考以下文章

android RecyclerView adapter 封装

android RecyclerView adapter 封装

android RecyclerView adapter 封装

android RecyclerView adapter 封装

RecyclerView 中的 YouTubePlayerFragment

RecyclerView的一些优化点