RecyclerViewAndroid 入门进阶Android 文章

RecyclerView完全解析(四)——与SwipeRefre

2017-07-02  本文已影响338人  _猜火车_
特别声明:

一、前言

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

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

二、SwipeRefreshLayout介绍

  • setOnRefreshListener(OnRefreshListener):添加下拉刷新监听器

三、RecyclerView+SwpieRefreshLayout实现下拉刷新效果

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

<?xmlversionxmlversion="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:androidLinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"  
    android:orientation="vertical"android:layout_width="match_parent"  
    android:layout_height="match_parent">  
    
    <android.support.v4.widget.SwipeRefreshLayout  
       android:id="@+id/demo_swiperefreshlayout"  
       android:layout_width="fill_parent"  
       android:layout_height="fill_parent"  
       android:scrollbars="vertical"  
        >  
       <android.support.v7.widget.RecyclerView  
           android:id="@+id/demo_recycler"  
           android:layout_width="fill_parent"  
           android:layout_height="fill_parent"  
           ></android.support.v7.widget.RecyclerView>  
   </android.support.v4.widget.SwipeRefreshLayout>  
</LinearLayout>  

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

demo_swiperefreshlayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {  
            @Override  
            public void onRefresh() {  
                Log.d("zttjiangqq","invoke onRefresh...");  
                new Handler().postDelayed(newRunnable() {  
                    @Override  
                    public void run() {  
                        List<String> newDatas = new ArrayList<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

public class RecyclerRefreshActivity extends BaseActivity {  
    private SwipeRefreshLayout demo_swiperefreshlayout;  
    private RecyclerView demo_recycler;  
    private RefreshRecyclerAdapter adapter;  
    private LinearLayoutManager linearLayoutManager;  
    private int lastVisibleItem;  
    @Override  
    protected void onCreate(BundlesavedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.recycler_refresh_layout);  
        
        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(false, 0, (int) TypedValue  
               .applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, 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(newRunnable() {  
                    @Override  
                    public void run() {  
                        List<String> newDatas = new ArrayList<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);  
            }  
        });  
          
}  

***RefreshRecyclerAdapter.java ***

public class RefreshRecyclerAdapter extends RecyclerView.Adapter<RefreshRecyclerAdapter.ViewHolder>{  
    private LayoutInflater mInflater;  
    private List<String> mTitles=null;  
    public RefreshRecyclerAdapter(Context context){  
       this.mInflater=LayoutInflater.from(context);  
        this.mTitles=new ArrayList<String>();  
        for (int i=0;i<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 Viewview=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> newDatas) {  
        //mTitles.add(position, data);  
        //notifyItemInserted(position);  
        newDatas.addAll(mTitles);  
        mTitles.removeAll(mTitles);  
        mTitles.addAll(newDatas);  
        notifyDataSetChanged();  
    }  
   
    public void addMoreItem(List<String> newDatas) {  
        mTitles.addAll(newDatas);  
        notifyDataSetChanged();  
    }  
}  

4、运行效果大致如下:

.gif

如无法显示图片:点击此链接查看

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

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

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

       //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> newDatas = new ArrayList<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实现上拉加载

我们来看RecyclerView.Apapter类:

上面有一个方法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布局项:

//返回的总条目数 +1
public intgetItemCount() {  
     return mTitles.size()+1;  
 }  

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

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的类型来选择指定的布局创建,返回即可:

public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
        //进行判断显示类型,来创建返回不同的View  
        if(viewType==TYPE_ITEM){  
            Viewview=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){  
            Viewfoot_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的类型来进行判定数据即可:

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){  
           FootViewHolderfootViewHolder=(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完整代码如下:

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 intTYPE_ITEM = 0;  //普通Item View  
    private static final intTYPE_FOOTER = 1;  //顶部FootView  
    public RefreshFootAdapter(Context context){  
       this.mInflater=LayoutInflater.from(context);  
        this.mTitles=new ArrayList<String>();  
        for (int i=0;i<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){  
            Viewview=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){  
            Viewfoot_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> newDatas) {  
        //mTitles.add(position, data);  
        //notifyItemInserted(position);  
        newDatas.addAll(mTitles);  
        mTitles.removeAll(mTitles);  
        mTitles.addAll(newDatas);  
        notifyDataSetChanged();  
    }  
   
    public void addMoreItem(List<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();  
    }  
}  

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

//设置滑动监听
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);  
                    newHandler().postDelayed(new Runnable() {  
                        @Override  
                        public void run() {  
                            List<String> newDatas = new ArrayList<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();  
            }  
 });  

8、运行效果大致如下:

六、最后总结

上一篇 下一篇

猜你喜欢

热点阅读