RecyclerView完全解析之下拉刷新与上拉加载

23 篇文章 0 订阅

RecyclerView完全解析之下拉刷新与上拉加载SwipeRefreshLayout

(一).前言:

话说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介绍:

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

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

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<  ?xml version = "1.0" encoding = "utf-8" ?>
<linearlayout xmlns :android = "http://schemas.android.com/apk/res/android"
    android :orientation = "vertical" android :layout_width = "match_parent"
    android :layout_height = "match_parent" >
     <include layout = "@layout/common_top_bar_layout" />
     <android . support. v4. widget. SwipeRefreshLayout
        android :id = "@+id/demo_swiperefreshlayout"
        android :layout_width = "fill_parent"
        android :layout_height = "fill_parent"
        android :scrollbars = "vertical"
         >
         </android ><android . support. v7. widget. RecyclerView
            android :id = "@+id/demo_recycler"
            android :layout_width = "fill_parent"
            android :layout_height = "fill_parent"
             ></android >
    
</linearlayout >

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

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

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

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

    @Override
     public ViewHolder onCreateViewHolder (ViewGroup parent,  int viewType )  {
         final  View view =mInflater. inflate (R. layout. item_recycler_layout,parent, false ) ;
         //这边可以做一些属性设置,甚至事件监听绑定
         //view.setBackgroundColor(Color.RED);
        ViewHolder viewHolder = new ViewHolder (view ) ;

         return viewHolder ;
     }

     /**
     * 数据的绑定显示
     * @param holder
     * @param position
     */

    @Override
     public  void onBindViewHolder (ViewHolder holder,  int position )  {
        holder. item_tv. setText (mTitles. get (position ) ) ;
        holder. itemView. setTag (position ) ;
     }
    @Override
     public  int getItemCount ( )  {
         return mTitles. size ( ) ;
     }

     //自定义的ViewHolder,持有每个Item的的所有界面元素
     public  static  class ViewHolder  extends RecyclerView. ViewHolder  {
         public TextView item_tv ;
         public ViewHolder ( View view ) {
             super (view ) ;
            item_tv  =  (TextView ) view. findViewById (R. id. item_tv ) ;
         }
     }

     //添加数据
     public  void addItem (List </string ><string > newDatas )  {
         //mTitles.add(position, data);
         //notifyItemInserted(position);
        newDatas. addAll (mTitles ) ;
        mTitles. removeAll (mTitles ) ;
        mTitles. addAll (newDatas ) ;
        notifyDataSetChanged ( ) ;
     }

     public  void addMoreItem (List </string ><string > newDatas )  {
        mTitles. addAll (newDatas ) ;
        notifyDataSetChanged ( ) ;
     }
}

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

5.运行效果如下:

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

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

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

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

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

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

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

运行效果如下:

(五).升级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:

1
2
private  static  final  int TYPE_ITEM  =  0 ;   //普通Item View
private  static  final  int TYPE_FOOTER  =  1 ;   //顶部FootView

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

1
2
3
public  int getItemCount ( )  {
         return mTitles. size ( ) + 1 ;
     }

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

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

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

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

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

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

6.整个RefreshFootAdapter完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package  com.chinaztt.fda.adapter ;
public  class RefreshFootAdapter  extends RecyclerView. Adapter <recyclerview . ViewHolder > {
     //上拉加载更多
     public  static  final  int  PULLUP_LOAD_MORE = 0 ;
     //正在加载中
     public  static  final  int  LOADING_MORE = 1 ;
     //上拉加载更多状态-默认为0
     private  int load_more_status = 0 ;
     private LayoutInflater mInflater ;
     private List <string > mTitles = null ;
     private  static  final  int TYPE_ITEM  =  0 ;   //普通Item View
     private  static  final  int TYPE_FOOTER  =  1 ;   //顶部FootView
     public RefreshFootAdapter ( Context context ) {
         this. mInflater =LayoutInflater. from (context ) ;
         this. mTitles = new ArrayList </string ><string > ( ) ;
         for  ( int i = 0 ;i &lt ; 20 ;i ++ ) {
             int index =i + 1 ;
            mTitles. add ( "item" +index ) ;
         }
     }
     /**
     * item显示类型
     * @param parent
     * @param viewType
     * @return
     */

     public RecyclerView. ViewHolder onCreateViewHolder (ViewGroup parent,  int viewType )  {
         //进行判断显示类型,来创建返回不同的View
         if (viewType ==TYPE_ITEM ) {
             View view =mInflater. inflate (R. layout. item_recycler_layout,parent, false ) ;
             //这边可以做一些属性设置,甚至事件监听绑定
             //view.setBackgroundColor(Color.RED);
            ItemViewHolder itemViewHolder = new ItemViewHolder (view ) ;
             return itemViewHolder ;
         } else  if (viewType ==TYPE_FOOTER ) {
             View foot_view =mInflater. inflate (R. layout. recycler_load_more_layout,parent, false ) ;
             //这边可以做一些属性设置,甚至事件监听绑定
             //view.setBackgroundColor(Color.RED);
            FootViewHolder footViewHolder = new FootViewHolder (foot_view ) ;
             return footViewHolder ;
         }
        return  null ;
     }

     /**
     * 数据的绑定显示
     * @param holder
     * @param position
     */

     public  void onBindViewHolder (RecyclerView. ViewHolder holder,  int position )  {
         if (holder  instanceof ItemViewHolder )  {
             ( (ItemViewHolder )holder ). item_tv. setText (mTitles. get (position ) ) ;
            holder. itemView. setTag (position ) ;
         } else  if (holder  instanceof FootViewHolder ) {
            FootViewHolder footViewHolder = (FootViewHolder )holder ;
             switch  (load_more_status ) {
                 case PULLUP_LOAD_MORE :
                    footViewHolder. foot_view_item_tv. setText ( "上拉加载更多..." ) ;
                     break ;
                 case LOADING_MORE :
                    footViewHolder. foot_view_item_tv. setText ( "正在加载更多数据..." ) ;
                     break ;
             }
         }
     }

     /**
     * 进行判断是普通Item视图还是FootView视图
     * @param position
     * @return
     */

    @Override
     public  int getItemViewType ( int position )  {
     // 最后一个item设置为footerView
     if  (position  +  1  == getItemCount ( ) )  {
                 return TYPE_FOOTER ;
             }  else  {
                 return TYPE_ITEM ;
             }
         }
    @Override
     public  int getItemCount ( )  {
         return mTitles. size ( ) + 1 ;
     }
     //自定义的ViewHolder,持有每个Item的的所有界面元素
     public  static  class ItemViewHolder  extends RecyclerView. ViewHolder  {
         public TextView item_tv ;
         public ItemViewHolder ( View view ) {
             super (view ) ;
            item_tv  =  (TextView ) view. findViewById (R. id. item_tv ) ;
         }
     }
     /**
     * 底部FootView布局
     */

     public  static  class FootViewHolder  extends  RecyclerView. ViewHolder {
         private TextView foot_view_item_tv ;
         public FootViewHolder ( View view )  {
             super (view ) ;
            foot_view_item_tv = (TextView )view. findViewById (R. id. foot_view_item_tv ) ;
         }
     }

     //添加数据
     public  void addItem (List </string ><string > newDatas )  {
         //mTitles.add(position, data);
         //notifyItemInserted(position);
        newDatas. addAll (mTitles ) ;
        mTitles. removeAll (mTitles ) ;
        mTitles. addAll (newDatas ) ;
        notifyDataSetChanged ( ) ;
     }

     public  void addMoreItem (List </string ><string > newDatas )  {
        mTitles. addAll (newDatas ) ;
        notifyDataSetChanged ( ) ;
     }

     /**
     * //上拉加载更多
     * PULLUP_LOAD_MORE=0;
     *  //正在加载中
     * LOADING_MORE=1;
     * //加载完成已经没有更多数据了
     * NO_MORE_DATA=2;
     * @param status
     */

     public  void changeMoreStatus ( int status ) {
        load_more_status =status ;
        notifyDataSetChanged ( ) ;
     }
}

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

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

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

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

8.运行效果如下:

(六).最后总结

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

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

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

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,下面是一个简单的示例代码: 首先,在XML布局文件中添加一个RecyclerView和SwipeRefreshLayout控件: ```xml <androidx.swiperefreshlayout.widget.SwipeRefreshLayout android:id="@+id/swipe_refresh_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" /> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> ``` 然后,在Activity或Fragment中初始化RecyclerView和SwipeRefreshLayout,并设置相应的监听器: ```java // 初始化RecyclerView和SwipeRefreshLayout mRecyclerView = findViewById(R.id.recycler_view); mSwipeRefreshLayout = findViewById(R.id.swipe_refresh_layout); // 设置布局管理器和适配器 mLayoutManager = new LinearLayoutManager(this); mAdapter = new MyAdapter(mDataList); mRecyclerView.setLayoutManager(mLayoutManager); mRecyclerView.setAdapter(mAdapter); // 设置下拉刷新监听器 mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { // 进行下拉刷新操作 refreshData(); } }); // 设置上加载更多监听器 mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (newState == RecyclerView.SCROLL_STATE_IDLE && isSlideToBottom(recyclerView)) { // 滑动到底部,触发加载更多操作 loadMoreData(); } } }); // 判断RecyclerView是否滑动到底部 private boolean isSlideToBottom(RecyclerView recyclerView) { LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); int lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition(); int itemCount = layoutManager.getItemCount(); return lastVisibleItemPosition == (itemCount - 1); } // 进行下拉刷新操作 private void refreshData() { // 在这里进行刷新数据的操作 // 刷新完成后调用mSwipeRefreshLayout.setRefreshing(false)停止刷新动画 } // 进行上加载更多操作 private void loadMoreData() { // 在这里进行加载更多数据的操作 // 加载完成后调用mAdapter.notifyDataSetChanged()更新列表 } ``` 需要注意的是,上述代码中的MyAdapter是自定义的RecyclerView适配器,需要根据实际情况进行修改。另外,刷新和加载更多操作需要在子线程中进行,可以使用AsyncTask等方式进行异步处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值