Android之RecyclerView轻松实现下拉刷新和加载更多示例

今天研究了下RecyclerView的滑动事件,特别是下拉刷新和加载更多事件,在现在几乎所有的APP显示数据列表时都用到了。自定义RecyclerView下拉刷新和加载更多听上去很复杂,实际上并不难,只要是对滑动事件的监听和处理。

一、自定义RecyclerView实现下拉刷新和加载更多

1、如何判断RecyclerView是在上滑还是下滑

在RecyclerView的OnScrollListener滑动事件监听中有个好用的方法,就是onScrolled(RecyclerView recyclerView, int dx, int dy),其中根据dx的值的正负就可以判断是在左滑还是右滑,而根据dy的值就可以判断是在上滑还是下滑。

//上滑
if(dy>0){
//相应操作代码
}
//下滑
else if(dy<0){
//相应操作代码
}

2、如何判断是否滑到了顶部或者底部

同样在RecyclerView的OnScrollListener滑动事件监听中onScrolled(RecyclerView recyclerView, int dx, int dy)方法中处理,根据canScrollVertically(int direction)来进行判断。

//是否滑到底部
if(!recyclerView.canScrollVertically(1)){
 //相应处理操作
}
//是否滑到顶部
if(!recyclerView.canScrollVertically(-1)){
 //相应处理操作
}

3、自定义RecyclerView

知道了滑动事件的判断和处理,就可以很轻松得实现下拉刷新和加载更多了。

import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;

/**
 * Package:com.liuting.library
 * author:liuting
 * Date:2017/2/14
 * Desc:自定义RecycleView,下拉刷新以及上拉加载更多
 */

public class RefreshLoadMoreRecycleView extends RecyclerView {
 private Boolean isLoadMore;//是否可以加载更多标志
 private Boolean isLoadEnd;//加载到最后的标志
 private Boolean isLoadStart;//顶部的标志
 private Boolean isRefresh;//是否可以下拉刷新标志
 private int lastVisibleItem;//最后一项
 private IOnScrollListener listener;//事件监听

 public RefreshLoadMoreRecycleView(Context context) {
  super(context);
  init(context);
 }

 public RefreshLoadMoreRecycleView(Context context, @Nullable AttributeSet attrs) {
  super(context, attrs);
  init(context);
 }

 public RefreshLoadMoreRecycleView(Context context, @Nullable AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);
  init(context);
 }

 public void init(Context context) {
  isLoadEnd=false;
  isLoadStart =true;

  this.addOnScrollListener(new RecyclerView.OnScrollListener() {
   @Override
   public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
    super.onScrollStateChanged(recyclerView, newState);
    //SCROLL_STATE_DRAGGING 和 SCROLL_STATE_IDLE 两种效果自己看着来
    if (newState == RecyclerView.SCROLL_STATE_IDLE) {
     if (isLoadEnd) {
      // 判断是否已加载所有数据
      if (isLoadMore) {//未加载完所有数据,加载数据,并且还原isLoadEnd值为false,重新定位列表底部
       if (getListener() != null) {
        getListener().onLoadMore();
       }
      } else {//加载完了所有的数据
       if(getListener()!=null){
        getListener().onLoaded();
       }
      }
      isLoadEnd = false;
     } else if (isLoadStart) {
      if(isRefresh){
       if (getListener() != null) {
        getListener().onRefresh();
       }
       isLoadStart=false;
      }
     }

    }
   }

   @Override
   public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
    super.onScrolled(recyclerView, dx, dy);
    //上滑
    if(dy>0){
     //是否滑到底部
     if(!recyclerView.canScrollVertically(1)){
      isLoadEnd = true;
     }else{
      isLoadEnd = false;
     }
    }
    //下滑
    else if(dy<0){
     //是否滑到顶部
     if(!recyclerView.canScrollVertically(-1)){
      isLoadStart=true;
     }else{
      isLoadStart=false;
     }
    }
   }
  });
 }

 //监听事件
 public interface IOnScrollListener {
  void onRefresh();

  void onLoadMore();

  void onLoaded();
 }

 public IOnScrollListener getListener() {
  return listener;
 }

 public void setListener(IOnScrollListener listener) {
  this.listener = listener;
 }

 public Boolean getLoadMore() {
  return isLoadMore;
 }

 //设置是否支持加载更多
 public void setLoadMoreEnable(Boolean loadMore) {
  isLoadMore = loadMore;
 }

 public Boolean getRefresh() {
  return isRefresh;
 }

 //设置是否支持下拉刷新
 public void setRefreshEnable(Boolean refresh) {
  isRefresh = refresh;
 }
}

二、实际用例

已经定义好了RecyclerView,下面在Demo中实际使用和处理。

1、定义布局

布局文件很简单,就是一个RecyclerView

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:id="@+id/activity_main"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical"
 tools:context="com.liuting.refreshloadmorelistview.MainActivity">

 <com.liuting.library.RefreshLoadMoreRecycleView
  android:id="@+id/main_recycle_view_data"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:scrollbars="none"
   />
</LinearLayout>

2、定义RecyclerView.Adapter

RecyclerView.Adapter在这里就简单处理了,列表布局直接使用Android自带的。

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.List;

/**
 * Package:com.liuting.refreshloadmorelistview.adapter
 * author:liuting
 * Date:2017/2/16
 * Desc:列表Adapter
 */

public class RefreshLoadMoreRecycleAdapter extends RecyclerView.Adapter<RefreshLoadMoreRecycleAdapter.ViewHolder> {
 private List<String> list;
 private Context context;

 public RefreshLoadMoreRecycleAdapter(Context context,List<String> list) {
  this.context =context;
  this.list = list;
 }

 @Override
 public RefreshLoadMoreRecycleAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  View view = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_expandable_list_item_1, parent, false);
  RefreshLoadMoreRecycleAdapter.ViewHolder viewHolder = new RefreshLoadMoreRecycleAdapter.ViewHolder(view);
  return viewHolder;
 }

 @Override
 public void onBindViewHolder(ViewHolder holder, int position) {
  holder.text.setText(list.get(position));
  holder.itemView.setTag(position);
 }

 @Override
 public int getItemCount() {
  return list.size();
 }

 class ViewHolder extends RecyclerView.ViewHolder{
  private TextView text;

  public ViewHolder(View itemView) {
   super(itemView);
   text=(TextView)itemView.findViewById(android.R.id.text1);
  }
 }
}

3、在Activity中定义好控件以及数据加载操作

实现自定义RecyclerView中的数据加载事件监听,刷新、加载更多以及加载完成。

import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.widget.Toast;

import com.liuting.library.RefreshLoadMoreRecycleView;
import com.liuting.refreshloadmorelistview.adapter.RefreshLoadMoreRecycleAdapter;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements RefreshLoadMoreRecycleView.IOnScrollListener{
 private RefreshLoadMoreRecycleView recycleView;//下拉刷新RecycleView
 private List<String> list;//列表
 private RefreshLoadMoreRecycleAdapter adapter;//Adapter
 private ProgressDialog dialog;//提示框
 private static final int REFRESH_Load=0;//下拉刷新
 private static final int MORE_Load=1;//加载更多
 private Handler handler =new Handler(){
  @Override
  public void handleMessage(Message msg) {
   super.handleMessage(msg);
   switch (msg.what){
    case REFRESH_Load:
     recycleView.setLoadMoreEnable(true);
     dismissDialog();
     if(list!=null){
      list.clear();
     }
     loadData();
     adapter.notifyDataSetChanged();
     break;
    case MORE_Load:
     recycleView.setLoadMoreEnable(false);
     dismissDialog();
     loadData();
     adapter.notifyDataSetChanged();
     break;
   }
  }
 };

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  initView();
 }

 public void initView(){
  dialog = new ProgressDialog(MainActivity.this);

  list=new ArrayList<>();
  loadData();
  recycleView = (RefreshLoadMoreRecycleView)findViewById(R.id.main_recycle_view_data);

  final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(MainActivity.this);
  recycleView.setLayoutManager(linearLayoutManager);
  adapter = new RefreshLoadMoreRecycleAdapter(MainActivity.this,list);
  recycleView.setAdapter(adapter);
  recycleView.setListener(this);
  recycleView.setRefreshEnable(true);
  recycleView.setLoadMoreEnable(true);
 }

 /**
  * 加载数据
  */
 public void loadData(){
  for(int i=0;i<10;i++ ){
   list.add("It is "+i);
  }
 }

 @Override
 public void onRefresh() {
  showDialog();
  new Thread(){
   @Override
   public void run() {
    super.run();
    try {
     sleep(5000);
     handler.sendEmptyMessage(REFRESH_Load);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
  }.start();
 }

 @Override
 public void onLoadMore() {
  showDialog();
  new Thread(){
   @Override
   public void run() {
    super.run();
    try {
     sleep(5000);
     handler.sendEmptyMessage(MORE_Load);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
  }.start();
 }

 @Override
 public void onLoaded() {
  Toast.makeText(MainActivity.this,"Loaded all",Toast.LENGTH_SHORT).show();
 }

 /**
  * dismiss dialog
  */
 private void dismissDialog(){
  if (dialog!=null&&dialog.isShowing()){
   dialog.dismiss();
  }
 }

 /**
  * show dialog
  */
 private void showDialog(){
  if (dialog!=null&&!dialog.isShowing()){
   dialog.show();
  }
 }
}

三、最终效果图

到这里就轻松实现了RecyclerView的下拉刷新和加载更多了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • RecyclerView下拉刷新上拉加载

    一 .前言 最近实在太忙,一个多礼拜没有更新文章了,于是今晚加班加点把demo写出来,现在都12点了才开始写文章. 1.我们的目标 把RecyclerView下拉刷新上拉加载更多加入到我们的开发者头条APP中. 2.效果图 3.实现步骤 找一个带上拉刷新下载加载更多的RecyclerView开源库,我们要站在巨人的肩膀上 下载下来自己先运行下demo,然后看看是不是我们需要的功能,觉得不错就把module依赖进来,整合主项目. 整合进来了之后,我们肯定需要进行修改,例如我这边就有滑动冲突,有多个

  • Android RecyclerView上拉加载和下拉刷新(基础版)

    这里讲述的是用谷歌原生的SwipeRefreshLayout,进行刷新,以及利用RecycleView的滚动事件,判断是否到最后一个item,进行加载更多,这里加载更多是在RecycleView的适配器中使用不同item进行完成的. 这是activity的xml布局: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.a

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

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

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

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

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

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

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

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

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

    之前写过一篇刷新加载<RecyclerView上拉加载和下拉刷新(基础版)> ,这次是进行改装完善. 代码中注释的很详细,所以就直接上代码了. 核心实现 package com.example.fly.recyclerviewrefresh.base; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.widget.SwipeRefreshLayout;

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

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

  • XRecyclerView实现下拉刷新、滚动到底部加载更多等功能

    介绍: 一个实现了下拉刷新,滚动到底部加载更多以及添加header功能的的RecyclerView.使用方式和RecyclerView完全一致,不需要额外的layout,不需要写特殊的adater. 加载效果内置了AVLoadingIndicatorView上的所有效果,可以根据需要指定. 项目地址:https://github.com/jianghejie/XRecyclerView 效果: 使用: xml <RelativeLayout xmlns:android="http://sc

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

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

随机推荐