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

本文主要介绍上拉加载和下拉刷新,Recyclerview实现复杂布局上篇文章已介绍:http://blog.youkuaiyun.com/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的!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值