基于Recyclerview实现复杂布局+SwipeRefreshLayout实现下拉刷新和上拉加载

来源:互联网 发布:淘宝分类全屏 编辑:程序博客网 时间:2024/04/28 12:22

本文主要介绍上拉加载和下拉刷新,Recyclerview实现复杂布局上篇文章已介绍:http://blog.csdn.net/qq_34501274/article/details/71194958


废话不多说直接进入正文:准备工作都不说了,自己先写好列表,本文主要讲解上拉加载和下拉刷新!


效果图

这里写图片描述


先看布局:

<?xml version="1.0" encoding="utf-8"?><android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:id="@+id/swipeRefreshLayout"    android:layout_width="match_parent"    android:layout_height="match_parent">    <android.support.v7.widget.RecyclerView        android:id="@+id/mRecyclerview"        android:layout_width="match_parent"        android:layout_height="match_parent">    </android.support.v7.widget.RecyclerView></android.support.v4.widget.SwipeRefreshLayout>

 下拉刷新

这个就很简单了,看具体操作!

  • 首先给swipeRefreshLayout设置下拉刷新监听
swipeRefreshLayout.setOnRefreshListener(this);//activity需要实现SwipeRefreshLayout.OnRefreshListener
  • 重写onRefresh()方法
 /**     * @param  ()下拉刷新实现     * */    @Override    public void onRefresh() {        new Handler().postDelayed(new Runnable() {            @Override            public void run() {                List<HomeModle> newDatas = new ArrayList<HomeModle>();                for (int i = 0; i <6; i++) {                    int index = i + 1;                    HomeModle homeModle=new HomeModle();                    homeModle.setText("new item" + index);                    newDatas.add(homeModle);                }                oneAdapter.addItem(newDatas);                swipeRefreshLayout.setRefreshing(false);                Toast.makeText(getActivity(), "更新了6条数据...", Toast.LENGTH_SHORT).show();            }        },3000);    }

这样下拉刷新就完成了!


上拉加载

我们需要在适配器去修改!

  • 思路
    1.我们需要在增加一个脚布局,用来显示,正在加载的状态
    2.监听recyclerview的滑动状态,当滑倒最后一个条目,仍有上拉状态就让其上拉加载数据
    整体的思路就是这两个,下面我们看具体操作

  • getItemCount 总长度需要加上脚布局的 所以需要总长度+1的

  • 在getItemViewType(int position)中,增加一个item类型,用来显示上拉加载的布局
// 可以这样写:根据position + 1 == getItemCount()判断,显示完所有列表后,给position+1 就显示上拉加载布局 @Override    public int getItemViewType(int position) {        /**         * 指定position显示返回对应的itemType         * */        if (position == 0) {//轮播图            return TYPE_SLIDER;        } else if (position == 1) {//排行榜图片及查看完整榜单            return TYPE_TYPE2;        } else if (position + 1 == getItemCount()) {//这是为了添加一个footerview            return TYPE_FOOTER;        } else {            return TYPE_TYPE3;        }    }
  • 在onCreateViewHolder中加载这个脚布局
   @Override    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        switch (viewType) {            case TYPE_SLIDER://轮播图                return new SliderViewHolder(inflater.inflate(R.layout.home_slider_type, parent, false));            case TYPE_TYPE2:                return new Type2ViewHolder(inflater.inflate(R.layout.home_type2, parent, false));            case TYPE_TYPE3:                return new TypeViewHolder(inflater.inflate(R.layout.home_type3, parent, false));            case TYPE_FOOTER://脚布局(用来显示上拉加载)                return new FooterViewHolder(inflater.inflate(R.layout.footerview, parent, false));            default:                return null;        }    }

//footerview.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="horizontal" android:layout_width="match_parent"    android:gravity="center_vertical"    android:layout_height="wrap_content">    <ProgressBar        android:layout_weight="1"        android:layout_width="0dp"        android:layout_height="wrap_content" />    <TextView        android:id="@+id/tv_load"        android:text="正在加载中。。。。。"        android:layout_weight="1"        android:layout_width="0dp"        android:layout_height="wrap_content" /></LinearLayout>
  • 可以在onBindViewHolder中设置加载时显示什么
   @Override    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {        if (holder instanceof SliderViewHolder) {//轮播图            bindItemTypeSlider((SliderViewHolder) holder, position);        } else if (holder instanceof Type2ViewHolder) {//排行榜            bindType2Head((Type2ViewHolder) holder, position);        } else if (holder instanceof TypeViewHolder) {//列表            bindType1((TypeViewHolder) holder, position);        } else if (holder instanceof FooterViewHolder) {//上啦加载            bindFooterView((FooterViewHolder) holder, position);        }    }

bindFooterView

    //上拉加载更多    public static final int PULLUP_LOAD_MORE = 0;    //正在加载中    public static final int LOADING_MORE = 1;    /**     * @param holder 上啦加载 显示布局     */    private void bindFooterView(FooterViewHolder holder, int position) {        FooterViewHolder footerViewHolder = (FooterViewHolder) holder;        switch (load_more_status) {            case PULLUP_LOAD_MORE:                footerViewHolder.tv_load_staus.setText("上拉加载更多...");                break;            case LOADING_MORE:                footerViewHolder.tv_load_staus.setText("正在加载更多数据...");                break;        }    }
  • 我们需要在adapter中对外暴露上拉加载的方法
 /**     * @param newDatas 下拉刷新时添加数据,要保证最新加载到的数据显示在最前面     *                 这里只是用string类型测试,后续需要采用modle。     */    public void addItem(List<HomeModle> newDatas) {        newDatas.addAll(list3);//先把之前的集合数据添加到这个新集合中。(newDatas,下拉刷新时用户调用,已有新数据,在添加原集合,这样新数据就显示到最前面)        list3.removeAll(list3);//清空这个原有的集合        list3.addAll(newDatas);//        notifyDataSetChanged();    }    /**     * @param loarMoreDatas 上啦加载更多,对外暴露方法     */    public void addMoreItem(List<HomeModle> loarMoreDatas) {        list3.addAll(loarMoreDatas);        notifyDataSetChanged();    }    /**     * @param status 加载状态,对外暴露方法     */    public void changeMoreStatus(int status) {        load_more_status = status;        notifyDataSetChanged();    }
  • 界面调用实现上拉加载数据

    首先设置recyclerview的滑动监听

  //添加滑动监听        mRecyclerview.addOnScrollListener(new RecyclerView.OnScrollListener() {            @Override            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {                super.onScrollStateChanged(recyclerView, newState);                if(newState ==RecyclerView.SCROLL_STATE_IDLE && lastVisibleItemPosition + 1 ==oneAdapter.getItemCount()){                    //上啦加载,添加数据                    loarmoreData();                }            }            @Override            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {                super.onScrolled(recyclerView, dx, dy);                //获取最后一个条目的位置                lastVisibleItemPosition = gridLayoutManager.findLastVisibleItemPosition();            }        });
 /**     * @param () 上啦加载     * */    private void loarmoreData() {        new Handler().postDelayed(new Runnable() {            @Override            public void run() {                List<HomeModle> loarmoreData = new ArrayList<HomeModle>();                for (int i = 0; i <6; i++) {                    HomeModle homeModle=new HomeModle();                    int index = i + 1;                    homeModle.setText("new item" + index);                    loarmoreData.add(homeModle);                }                oneAdapter.addMoreItem(loarmoreData);                oneAdapter.changeMoreStatus(FindAdapter.PULLUP_LOAD_MORE);                //这里调用了addMoreItem ,changeMoreStatus他们内部都刷新了adapter 所以adapter是刷新了两次  ,所以可以把changeMoreStatus,放到addMoreItem 里,其实实现上拉加载数据才是最重要的,至于加载中.加载完成这种状态要不要都行!这需要看个人其实现                Toast.makeText(getActivity(), "上啦加载了6条数据...", Toast.LENGTH_SHORT).show();            }        },2000);

到这里上拉加载就完成了!欢迎吐槽交流!


个人认为,其实自己去实现上拉加载和下拉刷新更简单,功能并不复杂,我们需要第一潜意识是考虑自己怎么实现,而不是第一时间去想,用哪个第三方!要是用第三方,还要去上网去看家怎么实现的!有时候第三方也有很多bug的!

阅读全文
0 0