一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Android RecyclerView上拉加载更多功能回弹实现代码

时间:2017-04-01 编辑:简简单单 来源:一聚教程网

实现原理是使用RecyclerView的OnTouchListener方法监听滑动 在adapter里面增加两项footview  其中date.size为显示的加载条,可以自定义,date.size+1为空白的View,我们设置其高度为0  我们通过LinearLayoutManager的  findLastVisibleItemPosition判断显示的最后一条数据,如果是空白view,表示加载条已经完全展示,松开即可刷新。

回弹效果是通过在滑动时动态改变空白view的高度,达到阻尼效果 ,回弹时再动态将其改为0,达到回弹效果,通过loading防止加载过程中滑动导致显示问题 这里的回调采用了Runnable传参

 

 代码如下复制代码

publicclassRefreshFootAdapterextends

    RecyclerView.Adapter{

  // 上拉加载更多

  publicstaticfinalintSATUS_PULLUP_LOAD_MORE =0;

  // 正在加载中

  publicstaticfinalintSATUS_LOADING_MORE =1;

  publicstaticfinalintSATUS_UP_LOADING_MORE =2;

  // 上拉加载更多状态-默认为0

  privateintload_more_status =0;

  privateLayoutInflater mInflater;

  privateListmTitles =null;

  privatestaticfinalintTYPE_ITEM =0;// 普通Item View

  privatestaticfinalintTYPE_FOOTER =1;// 底部FootView

  privatestaticfinalintTYPE_FOOTER_EMPTY =2;// 底部空白View

  privatestaticintpagesize;

  privateinteview_height =1;

  privatelongTimeFlag;// 回弹时间

  privateRecyclerView parent;

  privatebooleanloadmare;// 判断当前是可加载更多

  privatebooleanloading;// 判断是否正在加载

  privateintstartY, nowY;// 滑动判断

//构造函数 处理滑动监听 更新等功能

  publicRefreshFootAdapter(Context context, RecyclerView parent,

      finalLinearLayoutManager linearLayoutManager,intpagesize,

      finalRunnable onloadmore) {

    this.parent = parent;

    this.mInflater = LayoutInflater.from(context);

    this.mTitles =newArrayList();

    for(inti =0; i<20; i++) {

      intindex = i +1;

      mTitles.add("item"+ index);

    }

    this.pagesize = pagesize;

    parent.setOnTouchListener(newOnTouchListener() {

      @Override

      publicbooleanonTouch(View v, MotionEvent ev) {

        // TODO Auto-generated method stub

        switch(ev.getAction()) {

        caseMotionEvent.ACTION_MOVE:

          nowY = (int) ev.getY();

          if(RefreshFootAdapter.this.getItemCount() == linearLayoutManager

              .findLastVisibleItemPosition() +1) {

            if(startY ==0) {// 按下

              startY = nowY;

            }

            intchangeY = nowY - startY;

            RefreshFootAdapter.this

                .notifyEmptyView((int) (-changeY /1.3f));

            if(loading) {

              returnfalse;

            }

            RefreshFootAdapter.this

                .changeMoreStatus(RefreshFootAdapter.this.SATUS_UP_LOADING_MORE);

            loadmare =true;

          }else{

            loadmare =false;

            if(loading) {

              returnfalse;

            }

            RefreshFootAdapter.this

                .changeMoreStatus(RefreshFootAdapter.this.SATUS_PULLUP_LOAD_MORE);

            // 普通的滑动

            startY =0;

          }

          break;

        caseMotionEvent.ACTION_UP:

          RefreshFootAdapter.this.resetEmptyView();

          if(loadmare) {

            if(loading) {

              returnfalse;

            }else{

              RefreshFootAdapter.this

                  .changeMoreStatus(RefreshFootAdapter.this.SATUS_LOADING_MORE);

              if(onloadmore !=null&& !loading) {

                loading =true;

                onloadmore.run();

              }

            }

          }

          startY =0;

          break;

        default:

          break;

        }

        returnfalse;

      }

    });

  }

  /**

   * item显示类型

   *

   * @param parent

   * @param viewType

   * @return

   */

  publicRecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent,

      intviewType) {

    // 进行判断显示类型,来创建返回不同的View

    if(viewType == TYPE_ITEM) {

      View view = mInflater.inflate(R.layout.item_recycler_layout,

          parent,false);

      // 这边可以做一些属性设置,甚至事件监听绑定

      // view.setBackgroundColor(Color.RED);

      ItemViewHolder itemViewHolder =newItemViewHolder(view);

      returnitemViewHolder;

    }elseif(viewType == TYPE_FOOTER) {

      View foot_view = mInflater.inflate(

          R.layout.recycler_load_more_layout, parent,false);

      // 这边可以做一些属性设置,甚至事件监听绑定

      // view.setBackgroundColor(Color.RED);

      FootViewHolder footViewHolder =newFootViewHolder(foot_view);

      returnfootViewHolder;

    }elseif(viewType == TYPE_FOOTER_EMPTY) {

      View foot_view_empty = mInflater.inflate(

          R.layout.recycler_load_more_layout_empty, parent,false);

      // 这边可以做一些属性设置,甚至事件监听绑定

      // view.setBackgroundColor(Color.RED);

      FootEmptyHolder footEmptyViewHolder =newFootEmptyHolder(

          foot_view_empty);

      returnfootEmptyViewHolder;

    }

    returnnull;

  }

  /**

   * 数据的绑定显示

   *

   * @param holder

   * @param position

   */

  publicvoidonBindViewHolder(RecyclerView.ViewHolder holder,intposition) {

    if(holderinstanceofItemViewHolder) {

      ((ItemViewHolder) holder).item_tv.setText(mTitles.get(position));

      holder.itemView.setTag(position);

    }elseif(holderinstanceofFootViewHolder) {

      FootViewHolder footViewHolder = (FootViewHolder) holder;

      switch(load_more_status) {

      caseSATUS_PULLUP_LOAD_MORE:

        footViewHolder.foot_view_item_tv.setText("上拉加载更多...");

        break;

      caseSATUS_LOADING_MORE:

        footViewHolder.foot_view_item_tv.setText("正在加载更多数据...");

        break;

      caseSATUS_UP_LOADING_MORE:

        footViewHolder.foot_view_item_tv.setText("松开加载更多数据...");

        break;

      }

    }elseif(holderinstanceofFootEmptyHolder) {

      FootEmptyHolder footViewHolder = (FootEmptyHolder) holder;

      footViewHolder.empty.setLayoutParams(newViewGroup.LayoutParams(

          111, eview_height));

    }

  }

  /**

   * 进行判断是普通Item视图还是FootView视图

   *

   * @param position

   * @return

   */

  @Override

  publicintgetItemViewType(intposition) {

    // 最后一个item设置为footerView

    if(position +1== getItemCount()) {

      returnTYPE_FOOTER_EMPTY;

    }elseif(position +2== getItemCount()) {

      returnTYPE_FOOTER;

    }else{

      returnTYPE_ITEM;

    }

  }

//如果是页数的倍数 itemcount+2

  @Override

  publicintgetItemCount() {

    if(mTitles.size() % pagesize !=0) {

      returnmTitles.size();

    }else{

      returnmTitles.size() +2;

    }

    // return mTitles.size()+1;

  }

  // 自定义的ViewHolder,持有每个Item的的所有界面元素

  publicstaticclassItemViewHolderextendsRecyclerView.ViewHolder {

    publicTextView item_tv;

    publicItemViewHolder(View view) {

      super(view);

      item_tv = (TextView) view.findViewById(R.id.item_tv);

    }

  }

  /**

   * 底部FootView布局

   */

  publicstaticclassFootViewHolderextendsRecyclerView.ViewHolder {

    privateTextView foot_view_item_tv;

    publicFootViewHolder(View view) {

      super(view);

      foot_view_item_tv = (TextView) view

          .findViewById(R.id.foot_view_item_tv);

    }

  }

//空白项

  publicstaticclassFootEmptyHolderextendsRecyclerView.ViewHolder {

    privateView empty;

    publicFootEmptyHolder(View view) {

      super(view);

      empty = view.findViewById(R.id.empty);

    }

  }

  // 添加数据

  publicvoidaddItem(ListnewDatas) {

    // mTitles.add(position, data);

    // notifyItemInserted(position);

    newDatas.addAll(mTitles);

    mTitles.removeAll(mTitles);

    mTitles.addAll(newDatas);

    notifyDataSetChanged();

  }

//更新添加数据

  publicvoidaddMoreItem(ListnewDatas) {

    mTitles.addAll(newDatas);

    notifyDataSetChanged();

  }

//更新空白项高度

  privatevoidnotifyEmptyView(intheight) {

    this.eview_height = height;

    notifyItemChanged(getItemCount() -1);

  }

//空白回弹 伪回弹动画

  privatevoidresetEmptyView() {

    finalintdx = eview_height;

    newThread(newRunnable() {

      @Override

      publicvoidrun() {

        // TODO Auto-generated method stub

        finalinttime =500;

        finallongstartTime =newDate().getTime();

        TimeFlag = startTime;

        longnowTime =newDate().getTime();

        while(startTime + time > nowTime && TimeFlag == startTime) {

          nowTime =newDate().getTime();

          finalintdt = (int) (nowTime - startTime);

          parent.post(newRunnable() {

            @Override

            publicvoidrun() {

              // TODO Auto-generated method stub

              eview_height = eview_height * (time - dt) / time;

              notifyDataSetChanged();

            }

          });

          try{

            Thread.sleep(10);

          }catch(InterruptedException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

          }

        }

        parent.post(newRunnable() {

          @Override

          publicvoidrun() {

            // TODO Auto-generated method stub

            eview_height =0;

            notifyDataSetChanged();

          }

        });

      }

    }).start();

  }

//停止加载更多 重置loading状态和显示文本

  publicvoidstopLoadMore() {

    notifyDataSetChanged();

    loading =false;

    RefreshFootAdapter.this

    .changeMoreStatus(RefreshFootAdapter.this.SATUS_PULLUP_LOAD_MORE);

  }

  //改变加载条状态

  privatevoidchangeMoreStatus(intstatus) {

    if(loading) {

      return;

    }

    load_more_status = status;

    notifyDataSetChanged();

  }

}

 

图1为滑动过程

图2为松开加载

热门栏目