RecycleView 添加底部加载更多

2023-11-15

在阅读此文章前 请先看 http://blog.csdn.net/fangchao3652/article/details/43148871

与开头的连接文章思想类似,只不过那个是图片文字按钮等多种布局的混排,而添加底部只是普通Item 与底部Item两种布局的混排。那个是根据bean中的类型进行判断,然后在onCreateViewholder方法中创建不同的viewholder。而此文章先是根据getItemViewType方法判断item是哪中类型,然后成相应的viewholder.
那么我们就先来看一下getItemViewType方法:

  @Override
    public int getItemViewType(int position) {

        if (position == getContentItemCount() && useFooter()) {
            return TYPE_FOOTER;//若是最底下的item加载 footerviewholder
        }
        return Type_putong;//其他正常的item 
    }

然后就是onCreateViewHolder了(里面的两个方法等会贴出)

  @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == TYPE_FOOTER) {
            return onCreateFooterViewHolder(parent, viewType);
        }
        return onCreateContentItemViewHolder(parent, viewType - TYPE_ADAPTEE_OFFSET);
    }

既然创建了不同的viewholder 那绑定的时候也要根据 刚才的返回的viewholder的类型分别绑定:


  @Override
    public final void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        super.onBindViewHolder(holder,position);
        if (position == getContentItemCount() && holder.getItemViewType() == TYPE_FOOTER) {
            onBindFooterView(holder, position);//绑定底部item (可见性·赋值。。。)
        } else {
            onBindContentItemView(holder, position);//绑定普通的item
        }
    }
    //getContentItemCount 是在子类中实现的,获取全部数据的个数

好了主要的就这几个,好了,贴出完整代码:

//用的时候要继承此抽象类,然后实现里面的几个抽象方法即可。
public abstract class FooterAdapter extends BaseAnimAdapter{

    private static final int TYPE_FOOTER = Integer.MIN_VALUE;
    private static final int TYPE_ADAPTEE_OFFSET = 2;
    private boolean canLoadMore = false;

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == TYPE_FOOTER) {
            return onCreateFooterViewHolder(parent, viewType);
        }
        return onCreateContentItemViewHolder(parent, viewType - TYPE_ADAPTEE_OFFSET);
    }

    @Override
    public final void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        super.onBindViewHolder(holder,position);
        if (position == getContentItemCount() && holder.getItemViewType() == TYPE_FOOTER) {
            onBindFooterView(holder, position);
        } else {
            onBindContentItemView(holder, position);
        }
    }

    private static class ViewHolderFooter extends RecyclerView.ViewHolder {
        public ProgressBar pro;
        public TextView title;

        public ViewHolderFooter(View v) {
            super(v);
            pro = (ProgressBar) v.findViewById(R.id.pro);
            title = (TextView) v.findViewById(R.id.footerTitle);
        }
    }

    @Override
    public int getItemCount() {
        int itemCount = getContentItemCount();
        if (useFooter()) {
            itemCount += 1;
        }
        return itemCount;
    }

    @Override
    public int getItemViewType(int position) {

        if (position == getContentItemCount() && useFooter()) {
            return TYPE_FOOTER;
        }
        return getContentItemType(position) + TYPE_ADAPTEE_OFFSET;
    }

    public void setCanLoadMore(boolean canLoadMore){
        this.canLoadMore = canLoadMore;
    }

    public boolean isCanLoadMore() {
        return canLoadMore;
    }

    public abstract boolean useFooter();

    public RecyclerView.ViewHolder onCreateFooterViewHolder(ViewGroup parent, int viewType){
        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.footerview, parent, false);
        ViewHolderFooter vh = new ViewHolderFooter(v);
        return vh;
    }

    public void onBindFooterView(RecyclerView.ViewHolder holder, int position){
        ViewHolderFooter footerHolder = (ViewHolderFooter) holder;
        if (isCanLoadMore()) {
            footerHolder.pro.setVisibility(View.VISIBLE);
            footerHolder.title.setText("加载更多");
        } else {
            footerHolder.pro.setVisibility(View.GONE);
            footerHolder.title.setText("已到底部");
        }
    }

    public abstract RecyclerView.ViewHolder onCreateContentItemViewHolder(ViewGroup parent, int viewType);//创建你要的普通item 

    public abstract void onBindContentItemView(RecyclerView.ViewHolder holder, int position);//绑定数据

    public abstract int getContentItemCount();

    public abstract int getContentItemType(int position);//没用到,返回0即可,为了扩展用的
}

对了,他还有个父类,主要是定义了一个记载时的动画,看一下吧:

public abstract class BaseAnimAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
    private int lastPosition = -1;

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        setAnimation(holder.itemView, position);

    }

    private void setAnimation(View viewToAnimate, int position) {
        if (position > lastPosition) {
            Animation animation = AnimationUtils.loadAnimation(viewToAnimate.getContext(), R.anim.item_slide_bottom_up);
            viewToAnimate.startAnimation(animation);
            lastPosition = position;
        }
    }
}

到这布局控件什么的都有了,怎么上拉加载数据呢?我们来个监听器,并暴露一个onloadmore的抽象方法:

public abstract class RecyclerOnScrollListener extends RecyclerView.OnScrollListener {
    public static String TAG = RecyclerOnScrollListener.class.getSimpleName();
    private LinearLayoutManager manager;
    //用来标记是否正在向最后一个滑动,既是否向右滑动或向下滑动
    boolean isSlidingToLast = false;

    public RecyclerOnScrollListener(LinearLayoutManager linearLayoutManager) {
        this.manager = linearLayoutManager;
    }

    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        // 当不滚动时
        if (newState == RecyclerView.SCROLL_STATE_IDLE) {
            //获取最后一个完全显示的ItemPosition
            int lastVisibleItem = manager.findLastCompletelyVisibleItemPosition();
            int totalItemCount = manager.getItemCount();

            // 判断是否滚动到底部,并且是向右滚动
            if (lastVisibleItem == (totalItemCount - 1) && isSlidingToLast) {
                //加载更多功能的代码
                onLoadMore();
            }
        }
    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        //dx用来判断横向滑动方向,dy用来判断纵向滑动方向
        if (dx > 0 || dy > 0) {
            //大于0表示,正在向右滚动
            isSlidingToLast = true;
        } else {
            //小于等于0 表示停止或向左滚动
            isSlidingToLast = false;
        }

    }


    public abstract void onLoadMore();//要在实现类中实现

}

ok了,最后贴个demo吧:

@EActivity(R.layout.activity_recycler_view)
public class RecyclerViewActivity extends BaseActionBarActivity implements SwipeRefreshLayout.OnRefreshListener {
    @ViewById(R.id.swipe_container)
    SwipeRefreshLayout mSwipeLayout;
    @ViewById(R.id.recycler_view)
    RecyclerView mRecyclerView;
    private RecyclerViewAdapter mAdapter;
    private LinearLayoutManager mLayoutManager;
   List<String> myDataset;

    @AfterViews
    void initView() {

        //下拉刷新属性设置
        mSwipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
        mSwipeLayout.setOnRefreshListener(this);
        mSwipeLayout.setColorSchemeResources(android.R.color.holo_blue_bright,
                android.R.color.holo_green_light, android.R.color.holo_orange_light,
                android.R.color.holo_red_light);
        //设置固定大小
//        mRecyclerView.setHasFixedSize(true);
      /*  //设置item动画
        mRecyclerView.setItemAnimator(new SlideInOutBottomItemAnimator(mRecyclerView));

        mRecyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
*/
        //设置显示布局方式
        mLayoutManager = new LinearLayoutManager(this);
        mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerView.setOnScrollListener(new RecyclerOnScrollListener(mLayoutManager) {
            @Override
            public void onLoadMore() {


if(myDataset.size()<50) {
    myDataset.add("ccccc");
    myDataset.add("ccccc");
    myDataset.add("ccccc");
    myDataset.add("ccccc");
    myDataset.add("ccccc");
    myDataset.add("ccccc");
    myDataset.add("ccccc");
    myDataset.add("ccccc");
    mAdapter.setCanLoadMore(true);
}else
mAdapter.setCanLoadMore(false);
                mAdapter.notifyDataSetChanged();
            }
        });
        // specify an adapter (see also next example)
        myDataset = new ArrayList<>();
        myDataset.add("aa");
        myDataset.add("aa");
        myDataset.add("aa");
        myDataset.add("aa");
        myDataset.add("aa");
        myDataset.add("aa");
        myDataset.add("aa");
        myDataset.add("aa");
        myDataset.add("aa");
        myDataset.add("aa");
        myDataset.add("aa");
        myDataset.add("aa");
        myDataset.add("aa");
        myDataset.add("aa");
        myDataset.add("aa");
        mAdapter = new RecyclerViewAdapter(myDataset);
        mAdapter.setCanLoadMore(true);
        mRecyclerView.setAdapter(mAdapter);

    }

    @Override
    public void onRefresh() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                mSwipeLayout.setRefreshing(false);

//                mAdapter.notifyDataSetChanged();
                mAdapter.notifyItemInserted(0);
            }
        }, 2000);
    }


}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RecycleView 添加底部加载更多 的相关文章

随机推荐

  • Libsvm:脚本(subset.py、grid.py、checkdata.py)

    1 脚本 This directory includes some useful codes 1 subset selection tools 子集抽取工具 subset py 2 parameter selection tools 参数选
  • c#基础之WPF

    学习平台 微软开发者博客 DevBlogs Microsoft Developer Blogs 微软文档与学习 Microsoft Learn 培养开拓职业生涯新机遇的技能 微软开发者平台 Microsoft Developer WPF基础
  • Java-String类

    Java String类 1 概述 String 字符串 使用一对 引起来表示 String声明为final的 不可被继承 String实现了Serializable接口 表示字符串是支持序列化的 实现了Comparable接口 表示Str
  • Iptables封禁IP,记录地址

    前言 前段时间开了台国外的vps 以前机房的物理防火墙有十年网工大佬维护 我们对外访问的nginx上就没遇到过这种攻击 毕竟有问题的IP全被防火墙那层直接拦截了 而我这通过安全组把其中2个web端口放开了所有网段 而nginx再限制网段 导
  • 疫情日记(01)

    时间 2022年12月16日15 01 14 天气 阴天 地点 西安 12月8日全面放开以来 确诊这个词语也再是谈之色变了 似乎一旦 规定 疫情没有了 就真的没有了一样 两天前知道了ljc可能是确诊了 再后来就是办公室两个小兄弟 jc和qy
  • FAT文件系统初识

    最近在阅读 现代操作系统 的时候看到了fat32系统的讲解 在这里记录一下 我觉得fat32文件系统首先是基于链表分配的机制的 首先有一个基础知识 就是文件是由一系列的块组成的 想要访问完整的文件 就必须知道这个文件的所有的块的位置 链表分
  • Unity3d C#使用XCharts数据显示格式说明(如:数据类型、数据显示为百分比%等)

    前言 XCharts是开源且比较强大的插件 在Unity3d中搭建UI时常常使用的数据图表的制作插件 特别是当下的数字沙盘 数字孪生等项目中应用较广 笔者公司也一直在使用该插件 本文主要是在开发过程中的一个小需求引发的整理分享 在项目中需要
  • 前端自动化测试精讲

    单元测试 端对端测试 持续集成方案 在项目中落地前端自动化测试 作者介绍 祯民 字节跳动前端开发工程师 掘金小册 SSR实战 官网开发指南 作者 公众号 祯民讲前端 作者 曾负责 抖音前端技术团队官网 和 字节官网中文版 的开发 现维护抖音
  • git撤销加入暂存区(git add)的文件

    直接使用git reset加对应的文件或 来撤销 这个命令可以理解为git add的反向操作 可以撤销单个文件 也可批量 如 git reset xxx xxx xxx 或 git reset
  • C语言常见问题——++i与i++详解

    目录 一 i与i 1 引例 2 i i i 与 i i i 3 总结 二 函数中的 1 printf中的 2 作为函数的参数 3 总结 一 i与i 1 引例 对于如下程序 其输出结果是什么 include
  • 《算法导论》15章-动态规划 15.1 钢条切割(含有C++代码)

    一 引入 动态规划方法通常用来求解最优化问题 optimizationproblem 这类问题可以有很多可行解 每个解都有一个值 我们希望寻找具有最优值 最小值或最大值 的解 我们称这样的解为问 题的一个最优解 an optimal sol
  • 蓝桥杯2023年第十四届省赛真题python A组 (个人的做题记录,没有全对,可以通过部分测试点)

    试题 A 特殊日期 本题总分 5 分 问题描述 记一个日期为 yy 年 mm 月 dd 日 统计从 2000 年 1 月 1 日到 2000000 年 1 月 1 日 有多少个日期满足年份 yy 是月份 mm 的倍数 同时也是 dd 的倍数
  • 【ElasticSearch(五)进阶】两种_search检索方式,match_all检索,Query DSL基本使用...

    ElasticSearch 五 进阶 两种 search检索方式 match all检索 Query DSL基本使用 一 导入测试数据 ElasticSearch官方为我们准备了一部分测试数据供调试使用 我们可以Kinaba内进行数据导入处
  • SSH 整合Swagger2

    之前用的是springboot整合swagger2 新公司这边的系统是之前开发的 用的是SSH框架 这里记录一下 整合过程 以及遇到的坑 1 导入依赖
  • 华为OD机试 - 字符串分隔(C++ & Java & JS & Python)

    目录 描述 输入描述 输出描述 示例1 C 实现 Java实现 python实现 描
  • 如何提高oracle数据库的性能,关于提高Oracle数据库性能的四个误区

    为了提高性能 我们针对Oracle数据库本身提供了的方法或方案进行过不少的尝试 主要包括 共享服务器模式 MTS 集群技术 Clustering RAC 分区 并行处理 主要是并行查询 Oracle提供的这些特性确实是用来进行性能改善的 但
  • iOS证书申请打包上传App Store审核完整流程(7个步骤)

    上架基本需求资料 1 苹果开发者账号 2 开发好的APP 通过本篇教程 可以学习到ios证书申请和打包ipa上传到appstoreconnect apple com进行TestFlight测试然后提交审核的完整流程 上架App Store审
  • Golang JSON-序列化map,切片(slice),结构体(struct)

    package main import encoding json fmt func mapJson testMap make map string interface testMap name typ testMap age 123 te
  • python爬虫第9天 用爬虫测试网站 远程采集

    网站的前端通常并没 有自动化测试 尽管前端才是整个项目中真正与用户零距离接触的唯一一个部分 想象有一个由测试驱动的网络开发项目 每天进行测试以保证网络接口的每个环节的功能 都是正常的 每当有新的特性加入网站 或者一个元素的位置改变时 就执行
  • RecycleView 添加底部加载更多

    在阅读此文章前 请先看 http blog csdn net fangchao3652 article details 43148871 与开头的连接文章思想类似 只不过那个是图片文字按钮等多种布局的混排 而添加底部只是普通Item 与底部