当前位置: 移动技术网 > 移动技术>移动开发>Android > Android RecyclerView上拉加载更多功能回弹实现代码

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

2019年07月24日  | 移动技术网移动技术  | 我要评论

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

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

public class refreshfootadapter extends 
    recyclerview.adapter<recyclerview.viewholder> { 
  // 上拉加载更多 
  public static final int satus_pullup_load_more = 0; 
  // 正在加载中 
  public static final int satus_loading_more = 1; 
  public static final int satus_up_loading_more = 2; 
  // 上拉加载更多状态-默认为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 
  private static final int type_footer_empty = 2; // 底部空白view 
  private static int pagesize; 
  private int eview_height = 1; 
  private long timeflag;// 回弹时间 
  private recyclerview parent; 
  private boolean loadmare;// 判断当前是可加载更多 
  private boolean loading;// 判断是否正在加载 
  private int starty, nowy;// 滑动判断 
<span style="white-space:pre"> </span>//构造函数 处理滑动监听 更新等功能 
  public refreshfootadapter(context context, recyclerview parent, 
      final linearlayoutmanager linearlayoutmanager, int pagesize, 
      final runnable onloadmore) { 
    this.parent = parent; 
    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); 
    } 
    this.pagesize = pagesize; 
    parent.setontouchlistener(new ontouchlistener() { 
      @override 
      public boolean ontouch(view v, motionevent ev) { 
        // todo auto-generated method stub 
        switch (ev.getaction()) { 
        case motionevent.action_move: 
          nowy = (int) ev.gety(); 
          if (refreshfootadapter.this.getitemcount() == linearlayoutmanager 
              .findlastvisibleitemposition() + 1) { 
            if (starty == 0) {// 按下 
              starty = nowy; 
            } 
            int changey = nowy - starty; 
            refreshfootadapter.this 
                .notifyemptyview((int) (-changey / 1.3f)); 
            if (loading) { 
              return false; 
            } 
            refreshfootadapter.this 
                .changemorestatus(refreshfootadapter.this.satus_up_loading_more); 
            loadmare = true; 
          } else { 
            loadmare = false; 
            if (loading) { 
              return false; 
            } 
            refreshfootadapter.this 
                .changemorestatus(refreshfootadapter.this.satus_pullup_load_more); 
            // 普通的滑动 
            starty = 0; 
          } 
          break; 
        case motionevent.action_up: 
          refreshfootadapter.this.resetemptyview(); 
          if (loadmare) { 
            if (loading) { 
              return false; 
            } else { 
              refreshfootadapter.this 
                  .changemorestatus(refreshfootadapter.this.satus_loading_more); 
              if (onloadmore != null && !loading) { 
                loading = true; 
                onloadmore.run(); 
              } 
            } 
          } 
          starty = 0; 
          break; 
        default: 
          break; 
        } 
        return false; 
      } 
    }); 
  } 
  /** 
   * 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; 
    } else if (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 = new footemptyholder( 
          foot_view_empty); 
      return footemptyviewholder; 
    } 
    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 satus_pullup_load_more: 
        footviewholder.foot_view_item_tv.settext("上拉加载更多..."); 
        break; 
      case satus_loading_more: 
        footviewholder.foot_view_item_tv.settext("正在加载更多数据..."); 
        break; 
      case satus_up_loading_more: 
        footviewholder.foot_view_item_tv.settext("松开加载更多数据..."); 
        break; 
      } 
    } else if (holder instanceof footemptyholder) { 
      footemptyholder footviewholder = (footemptyholder) holder; 
      footviewholder.empty.setlayoutparams(new viewgroup.layoutparams( 
          111, eview_height)); 
    } 
  } 
  /** 
   * 进行判断是普通item视图还是footview视图 
   * 
   * @param position 
   * @return 
   */ 
  @override 
  public int getitemviewtype(int position) { 
    // 最后一个item设置为footerview 
    if (position + 1 == getitemcount()) { 
      return type_footer_empty; 
    } else if (position + 2 == getitemcount()) { 
      return type_footer; 
    } else { 
      return type_item; 
    } 
  } 
<span style="white-space:pre"> </span>//如果是页数的倍数 itemcount+2 
  @override 
  public int getitemcount() { 
    if (mtitles.size() % pagesize != 0) { 
      return mtitles.size(); 
    } else { 
      return mtitles.size() + 2; 
    } 
    // 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); 
    } 
  } 
<span style="white-space:pre"> </span>//空白项 
  public static class footemptyholder extends recyclerview.viewholder { 
    private view empty; 
    public footemptyholder(view view) { 
      super(view); 
      empty = view.findviewbyid(r.id.empty); 
    } 
  } 
  // 添加数据 
  public void additem(list<string> newdatas) { 
    // mtitles.add(position, data); 
    // notifyiteminserted(position); 
    newdatas.addall(mtitles); 
    mtitles.removeall(mtitles); 
    mtitles.addall(newdatas); 
    notifydatasetchanged(); 
  } 
<span style="white-space:pre"> </span>//更新添加数据 
  public void addmoreitem(list<string> newdatas) { 
    mtitles.addall(newdatas); 
    notifydatasetchanged(); 
  } 
<span style="white-space:pre"> </span>//更新空白项高度 
  private void notifyemptyview(int height) { 
    this.eview_height = height; 
    notifyitemchanged(getitemcount() - 1); 
  } 
<span style="white-space:pre"> </span>//空白回弹 伪回弹动画 
  private void resetemptyview() { 
    final int dx = eview_height; 
    new thread(new runnable() { 
      @override 
      public void run() { 
        // todo auto-generated method stub 
        final int time = 500; 
        final long starttime = new date().gettime(); 
        timeflag = starttime; 
        long nowtime = new date().gettime(); 
        while (starttime + time > nowtime && timeflag == starttime) { 
          nowtime = new date().gettime(); 
          final int dt = (int) (nowtime - starttime); 
          parent.post(new runnable() { 
            @override 
            public void run() { 
              // 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(new runnable() { 
          @override 
          public void run() { 
            // todo auto-generated method stub 
            eview_height = 0; 
            notifydatasetchanged(); 
          } 
        }); 
      } 
    }).start(); 
  } 
<span style="white-space:pre"> </span>//停止加载更多 重置loading状态和显示文本 
  public void stoploadmore() { 
    notifydatasetchanged(); 
    loading = false; 
    refreshfootadapter.this 
    .changemorestatus(refreshfootadapter.this.satus_pullup_load_more); 
  } 
  //改变加载条状态 
  private void changemorestatus(int status) { 
    if (loading) { 
      return; 
    } 
    load_more_status = status; 
    notifydatasetchanged(); 
  } 
} 

图1为滑动过程

图2为松开加载

以上所述是小编给大家介绍的android recyclerview上拉加载更多功能回弹实现代码,希望对大家有所帮助

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网