当前位置: 首页 > news >正文

RecycleView + SwipeRefreshLayout 实现下拉刷新和底部自动加载

前段时间项目里面使用了RecycleView 但是里面的刷新和加载都是框架里面封装好的,直接使用

这几天比较闲就自己来实现以下.

因为SwipeRefreshLayout是一个下拉刷新控件所有直接和RecycleView结合使用就行了

布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    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"
    tools:context="tianliang.com.mvpdemo.MainActivity">
    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/SwipeRefreshLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <android.support.v7.widget.RecyclerView
            android:id="@+id/RecyclerView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
        </android.support.v7.widget.RecyclerView>
    </android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>

 主代码

在里面使用了 butterknife 关联控件

public class MainActivity extends AppCompatActivity {

    @Nullable
    @BindView(R.id.RecyclerView)
    RecyclerView mRecyclerView;
    @Nullable
    @BindView(R.id.SwipeRefreshLayout)
    SwipeRefreshLayout mSwipeRefreshLayout;

    private LinearLayoutManager mLayoutManager;
    private List<String> data;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        initData();
    }

    private void initData() {
        mLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mLayoutManager);
        //初始化数据
        data = new ArrayList<>();
        for (int i = 1; i < 30; i++) {
            data.add("数据+" + i);
        }
        RecyclerViewAdapter mAdapter = new RecyclerViewAdapter(data);//设置adpater
        mRecyclerView.setAdapter(mAdapter);
    //SwipeRefreshLayout监听 mSwipeRefreshLayout.setOnRefreshListener(
new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() {//模仿加载网络数据 new Handler().postDelayed(new Runnable() { @Override public void run() {//每次刷新一条数据 data.add(0, "刷新出来的数据"); mRecyclerView.getAdapter().notifyDataSetChanged(); mSwipeRefreshLayout.setRefreshing(false); } }, 2000); } });
    mRecyclerView.setOnScrollListener(new OnRcvScrollListener(){//使用自定义的RecycleView的底部监听
     @Override
     public void onBottom() {//接口回调
     new Handler().postDelayed(new Runnable() {//模仿网络请求
     @Override
      public void run() {
     if (data.size() <= 50) {
   for (int i = 1; i < 5; i++) {
   data.add("加载更多+" + i);
   }
   }
   mRecyclerView.getAdapter().notifyDataSetChanged();//刷新adapter
   }
   }, 2000);
   }
  }
);
 
  } 
}
RecycleView的底部监听
使用的是  http://www.cnblogs.com/tianzhijiexian/p/4397552.html 写好的工具类
public abstract class OnRcvScrollListener extends RecyclerView.OnScrollListener implements OnBottomListener {

    private String TAG = getClass().getSimpleName();

    public static enum LAYOUT_MANAGER_TYPE {
        LINEAR,
        GRID,
        STAGGERED_GRID
    }

    /**
     * layoutManager的类型(枚举)
     */
    protected LAYOUT_MANAGER_TYPE layoutManagerType;

    /**
     * 最后一个的位置
     */
    private int[] lastPositions;

    /**
     * 最后一个可见的item的位置
     */
    private int lastVisibleItemPosition;
/*    *//**
     * 是否正在加载
     *//*
    private boolean isLoadingMore = false;*/

    /**
     * 当前滑动的状态
     */
    private int currentScrollState = 0;

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);

        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        //  int lastVisibleItemPosition = -1;
        if (layoutManagerType == null) {
            if (layoutManager instanceof LinearLayoutManager) {
                layoutManagerType = LAYOUT_MANAGER_TYPE.LINEAR;
            } else if (layoutManager instanceof GridLayoutManager) {
                layoutManagerType = LAYOUT_MANAGER_TYPE.GRID;
            } else if (layoutManager instanceof StaggeredGridLayoutManager) {
                layoutManagerType = LAYOUT_MANAGER_TYPE.STAGGERED_GRID;
            } else {
                throw new RuntimeException(
                        "Unsupported LayoutManager used. Valid ones are LinearLayoutManager, GridLayoutManager and StaggeredGridLayoutManager");
            }
        }

        switch (layoutManagerType) {
            case LINEAR:
                lastVisibleItemPosition = ((LinearLayoutManager) layoutManager)
                        .findLastVisibleItemPosition();
                break;
            case GRID:
                lastVisibleItemPosition = ((GridLayoutManager) layoutManager)
                        .findLastVisibleItemPosition();
                break;
            case STAGGERED_GRID:
                StaggeredGridLayoutManager staggeredGridLayoutManager
                        = (StaggeredGridLayoutManager) layoutManager;
                if (lastPositions == null) {
                    lastPositions = new int[staggeredGridLayoutManager.getSpanCount()];
                }
                staggeredGridLayoutManager.findLastVisibleItemPositions(lastPositions);
                lastVisibleItemPosition = findMax(lastPositions);
                break;
        }

    }

    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        currentScrollState = newState;
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        int visibleItemCount = layoutManager.getChildCount();
        int totalItemCount = layoutManager.getItemCount();
        if ((visibleItemCount > 0 && currentScrollState == RecyclerView.SCROLL_STATE_IDLE &&
                (lastVisibleItemPosition) >= totalItemCount - 1)) {
            onBottom();
        }
    }


    @Override
    public abstract void onBottom() ;

    private int findMax(int[] lastPositions) {
        int max = lastPositions[0];
        for (int value : lastPositions) {
            if (value > max) {
                max = value;
            }
        }
        return max;
    }
}

回调接口

public interface OnBottomListener {
    void onBottom();
}

apdater

根据条目是否是最后一条来显示对应的hoder

public class RecyclerViewAdapter extends RecyclerView.Adapter {
    private final List<String> mData;
    private int TYPE_FOOTER = 1;//加载更多
    private int TYPE_NORMAL = 0;//itme

    public RecyclerViewAdapter(List<String> data) {
        mData = data;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == TYPE_FOOTER) {//加载更多
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapet, parent, false);
            footerHodler footer = new footerHodler(view,mData);
            return footer;
        }
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.itmeadapet, parent, false);
        itmeHoder hoder = new itmeHoder(view, mData.get(viewType));
        return hoder;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (getItemViewType(position) == TYPE_NORMAL && holder instanceof itmeHoder) {
            ((itmeHoder) holder).setData(mData.get(position));
        }else if (getItemViewType(position) == TYPE_FOOTER && holder instanceof footerHodler){
            ((footerHodler)holder).setData();
        }
    }

    @Override
    public int getItemCount() {
        return mData.size() + 1;
    }

    @Override
    public int getItemViewType(int position) {
        if (position == getItemCount() - 1) {
            return TYPE_FOOTER;//最后一条数据
        }
        return TYPE_NORMAL;
    }
}

ok,大体就是这样了

 

转载于:https://www.cnblogs.com/wuwenweihe/p/7230383.html

相关文章:

  • hive中间接实现不等值连接
  • python之字符编码
  • Hadoop计算文件大小
  • 在Oracle中利用SQL_TRACE跟踪SQL的执行
  • Linux添加/删除用户和用户组
  • Hive优化(3)之随机数避免数据倾斜
  • Angular2学习(一)
  • hive优化(4)之mapjoin和union all避免数据倾斜
  • hive cli
  • Hive优化(5)之选择合适的map数
  • C++ 文件操作(CFile类)
  • Hadoop MapReduce:详解Shuffle过程
  • 编译树莓派2代B型OpenWrt固件实现无线路由器及nodogsplash认证功能
  • 为什么一些公司把dwg文件转化为pdf
  • hadoop生态系统
  • [NodeJS] 关于Buffer
  • [译]CSS 居中(Center)方法大合集
  • 5、React组件事件详解
  • es6(二):字符串的扩展
  • Flannel解读
  • JS+CSS实现数字滚动
  • node 版本过低
  • Selenium实战教程系列(二)---元素定位
  • Shadow DOM 内部构造及如何构建独立组件
  • ubuntu 下nginx安装 并支持https协议
  • ucore操作系统实验笔记 - 重新理解中断
  • Vultr 教程目录
  • 个人博客开发系列:评论功能之GitHub账号OAuth授权
  • 跨域
  • 每天10道Java面试题,跟我走,offer有!
  • 说说动画卡顿的解决方案
  • 小程序开发之路(一)
  • 一道闭包题引发的思考
  • 《天龙八部3D》Unity技术方案揭秘
  • 【云吞铺子】性能抖动剖析(二)
  • 回归生活:清理微信公众号
  • #LLM入门|Prompt#1.7_文本拓展_Expanding
  • #LLM入门|Prompt#3.3_存储_Memory
  • (01)ORB-SLAM2源码无死角解析-(56) 闭环线程→计算Sim3:理论推导(1)求解s,t
  • (14)Hive调优——合并小文件
  • (175)FPGA门控时钟技术
  • (23)Linux的软硬连接
  • (十一)手动添加用户和文件的特殊权限
  • (转)创业的注意事项
  • (转载)Google Chrome调试JS
  • ****** 二十三 ******、软设笔记【数据库】-数据操作-常用关系操作、关系运算
  • .bat批处理(八):各种形式的变量%0、%i、%%i、var、%var%、!var!的含义和区别
  • .NET 4.0网络开发入门之旅-- 我在“网” 中央(下)
  • .NET core 自定义过滤器 Filter 实现webapi RestFul 统一接口数据返回格式
  • .NET Core6.0 MVC+layui+SqlSugar 简单增删改查
  • .NET 应用架构指导 V2 学习笔记(一) 软件架构的关键原则
  • .NET4.0并行计算技术基础(1)
  • .Net调用Java编写的WebServices返回值为Null的解决方法(SoapUI工具测试有返回值)
  • .NET设计模式(11):组合模式(Composite Pattern)
  • .Net中间语言BeforeFieldInit