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

实现原理是使用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上拉加载更多功能回弹实现代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • Android RecyclerView添加上拉加载更多效果

    先看一下效果 刷新的时候是这样的: 没有更多的时候是这样的: 既然有刷新的时候有两种状态就要定义两个状态 //普通布局的type static final int TYPE_ITEM = 0; //脚布局 static final int TYPE_FOOTER = 1; 在特定的时候去显示: @Override public int getItemViewType(int position) { //如果position加1正好等于所有item的总和,说明是最后一个item,将它设置为脚布局

  • RecyclerView上拉加载封装代码

    RecyclerView上拉加载,先看效果: 网上有很多这类得框架,不过在自己的项目只用到上拉加载的功能,所以自己封装一个简单点的. 主要依赖BaseRecyPRAdapter这类 public abstract class BaseRecyPRAdapter<T> extends RecyclerView.Adapter<BaseRecyPRAdapter.BaseViewHolder> { private static final String TAG = "Base

  • Android使用recyclerview打造真正的下拉刷新上拉加载效果

    前言 前段时间需要用到recyclerview,就想找个封装好的下拉刷新,上拉加载的库,结果愣是没找到,便自己写了一个. 注意:我说的是"上拉加载",不是滑到底部自动加载. 虽然现在自动加载是主流和趋势,但也不排除有时候就需要用到上拉加载啊,毕竟林子大了,什么样的产品经理都有对吧. 代码写好后,准备发布到bintray的时候,向同事征求这个项目的名字,同事说:"就叫DZTRecyclerview!" 不解,同事解释:"叼炸天Recyclerview!&qu

  • Android RecyclerView添加上拉加载更多功能

    上一篇文章已经介绍了如何为RecyclerView添加FootView,在此基础上,要添加分页加载的功能其实已经很简单了. 上一篇文章地址:为RecyclerView添加FootView和HeadView 效果:(源码在文章结尾) 实现关键 在上一篇代码的基础上,只需要在onBindViewHolder(ViewHolder holder, int position)函数中添加一定修改就可以了,如下: @Override public void onBindViewHolder(ViewHold

  • Android RecyclerView下拉刷新和上拉加载更多

    今天终于有点时间,来写了一下: 为RecyclerView实现下拉刷新和上拉加载更多.今天会在前面的两篇文章的基础上: RecyclerView系列之(1):为RecyclerView添加Header和Footer RecyclerView系列之(2):为RecyclerView添加分隔线 继续讲述RecyclerView中一些常用组件的实现下拉刷新和上拉加载更多的功能. 在现在的Android手机应用中,几乎每一个APP都有下拉刷新和上拉加载更多的功能,它们的重要性不言而喻. 先不多说,先看效

  • android RecyclerView侧滑菜单,滑动删除,长按拖拽,下拉刷新上拉加载

    本文介绍的库中的侧滑效果借鉴自SwipeMenu,并对SipwMenu的源码做了修改与Bug修复,然后才开发出的SwipeRecyclerView. 需要说明的是,本库没有对RecyclerView做大的修改,只是ItemView的封装.看起来是对RecyclerView的修改,其实仅仅是为RecyclerView添加了使用的方法API而已. 本库已经更新了三个版本了,会一直维护下去,根据小伙伴的要求,以后也会添加一些其它功能. SwipeRecyclerView将完美解决这些问题: 以下功能全

  • Android RecyclerView实现下拉刷新和上拉加载

    RecyclerView已经出来很久了,许许多多的项目都开始从ListView转战RecyclerView,那么,上拉加载和下拉刷新是一件很有必要的事情. 在ListView上,我们可以通过自己添加addHeadView和addFootView去添加头布局和底部局实现自定义的上拉和下拉,或者使用一些第三方库来简单的集成,例如Android-pulltorefresh或者android-Ultra-Pull-to-Refresh,后者的自定义更强,但需要自己实现上拉加载. 而在下面我们将用两种方式

  • Android RecyclerView实现下拉刷新和上拉加载更多

    使用官方的刷新控件SwipeRefreshLayout来实现下拉刷新,当RecyclerView滑到底部实现下拉加载(进度条效果用RecyclerView加载一个布局实现) 需要完成控件的下拉监听和上拉监听,其中,下拉监听通过SwipRefreshLayout的setOnRefreshListener()方法监听,而上拉刷新,需要通过监听列表的滚动,当列表滚动到底部时触发事件,具体代码如下 主布局 <?xml version="1.0" encoding="utf-8&

  • Android中使用RecyclerView实现下拉刷新和上拉加载

    推荐阅读:使用RecyclerView添加Header和Footer的方法                       RecyclerView的使用之HelloWorld RecyclerView 是Android L版本中新添加的一个用来取代ListView的SDK,它的灵活性与可替代性比listview更好.本文给大家介绍如何为RecyclerView添加下拉刷新和上拉加载,过去在ListView当中添加下拉刷新和上拉加载是非常方便的利用addHeaderView和addFooterVie

  • Android RecyclerView 上拉加载更多及下拉刷新功能的实现方法

    RecyclerView 已经出来很久了,但是在项目中之前都使用的是ListView,最近新的项目上了都大量的使用了RecycleView.尤其是瀑布流的下拉刷新,网上吧啦吧啦没有合适的自己总结了一哈. 先贴图上来看看: 使用RecyclerView实现上拉加载更多和下拉刷新的功能我自己有两种方式: 1.使用系统自带的Android.support.v4.widget.SwipeRefreshLayout这个控价来实现. 2.自定义的里面带有RecyleView的控件. 使用RecycleVie

随机推荐