前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >RecyclerView添加头部和底部视图的实现

RecyclerView添加头部和底部视图的实现

作者头像
听着music睡
发布于 2018-05-18 08:09:57
发布于 2018-05-18 08:09:57
3K00
代码可运行
举报
文章被收录于专栏:Android干货Android干货
运行总次数:0
代码可运行

ListView是有addHeaderView和 addFooterView两个方法的.

但是作为官方推荐的ListView的升级版RecyclerView缺无法实现这两个方法。

那么如果使用RecyclerView实现这两个方法的效果该怎么做呢?

网上查询了很久,试过各种各样的实现方式,终于让我发现一个还不错的实现方法,那么就给大家推荐一下。

项目地址(别人写的,非博主的)https://github.com/jczmdeveloper/XCRecyclerView

我看了下这个源码,很简单,即写了一个继承RecyclerView的控件,自己实现addHeaderView和addFooterView两个方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.xqx.com.recyclerviewheaderdemo;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

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


public class XCRecyclerView extends RecyclerView{

    private ArrayList<View> mHeaderViews = new ArrayList<>();
    private ArrayList<View> mFooterViews = new ArrayList<>();
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.Adapter mWrapAdapter;
    private static final int TYPE_HEADER = -101;
    private static final int TYPE_FOOTER  = -102;
    private static final int TYPE_LIST_ITEM = - 103;
    public XCRecyclerView(Context context) {
        this(context, null);
    }
    public XCRecyclerView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public XCRecyclerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }
    private void init(Context context){

    }

    @Override
    public void setAdapter(Adapter adapter) {
        mAdapter = adapter;
        mWrapAdapter = new WrapAdapter(mHeaderViews, mFooterViews, adapter);
        super.setAdapter(mWrapAdapter);
        mAdapter.registerAdapterDataObserver(mDataObserver);
    }
    public void addHeaderView(View view){
        mHeaderViews.clear();
        mHeaderViews.add(view);
    }
    public void addFooterView(View view){
        mFooterViews.clear();
        mFooterViews.add(view);
    }
    public int getHeaderViewsCount(){
        return mHeaderViews.size();
    }
    public int getFooterViewsCount(){
        return mFooterViews.size();
    }
    private final RecyclerView.AdapterDataObserver mDataObserver = new RecyclerView.AdapterDataObserver() {
        @Override
        public void onChanged() {
            mWrapAdapter.notifyDataSetChanged();
        }

        @Override
        public void onItemRangeChanged(int positionStart, int itemCount) {
            mWrapAdapter.notifyItemRangeChanged(positionStart, itemCount);
        }

//        @Override
//        public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
//            mWrapAdapter.notifyItemRangeChanged(positionStart, itemCount, payload);
//        }

        @Override
        public void onItemRangeInserted(int positionStart, int itemCount) {
            mWrapAdapter.notifyItemRangeInserted(positionStart, itemCount);
        }

        @Override
        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
            mWrapAdapter.notifyItemMoved(fromPosition, toPosition);
        }

        @Override
        public void onItemRangeRemoved(int positionStart, int itemCount) {
            mWrapAdapter.notifyItemRangeRemoved(positionStart, itemCount);
        }
    };
    private class WrapAdapter extends RecyclerView.Adapter<ViewHolder>{

        private Adapter mAdapter;
        private List<View> mHeaderViews;
        private List<View> mFooterViews;
        public WrapAdapter(List<View> headerViews,List<View> footerViews,Adapter adapter){
            this.mAdapter = adapter;
            this.mHeaderViews = headerViews;
            this.mFooterViews = footerViews;
        }

        public int getHeaderCount(){
            return this.mHeaderViews.size();
        }
        public int getFooterCount(){
            return this.mFooterViews.size();
        }
        public boolean isHeader(int position){
            return position >= 0 && position < this.mHeaderViews.size();
        }
        public boolean isFooter(int position){
            return position < getItemCount() && position >= getItemCount() - this.mFooterViews.size();
        }
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            if(viewType == TYPE_HEADER){
                return new CustomViewHolder(this.mHeaderViews.get(0));
            }else if(viewType == TYPE_FOOTER){
                return new CustomViewHolder(this.mFooterViews.get(0));
            }else{
                return this.mAdapter.onCreateViewHolder(parent,viewType);
            }
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            if(isHeader(position)) return;
            if(isFooter(position)) return;
            int rePosition = position - getHeaderCount();
            int itemCount = this.mAdapter.getItemCount();
            if(this.mAdapter != null){
                if(rePosition < itemCount){
                    Log.v("czm","rePosition/itemCount="+rePosition+"/"+itemCount);
                    this.mAdapter.onBindViewHolder(holder,rePosition);
                    return;
                }
            }
        }
        @Override
        public long getItemId(int position) {
            if (this.mAdapter != null && position >= getHeaderCount()) {
                int rePosition = position - getHeaderCount();
                int itemCount = this.mAdapter.getItemCount();
                if (rePosition < itemCount) {
                    return this.mAdapter.getItemId(rePosition);
                }
            }
            return -1;
        }
        @Override
        public int getItemViewType(int position) {
            if(isHeader(position)){
                return TYPE_HEADER;
            }
            if(isFooter(position)){
                return TYPE_FOOTER;
            }
            int rePosition = position - getHeaderCount();
            int itemCount = this.mAdapter.getItemCount();
            if(rePosition < itemCount){
                return this.mAdapter.getItemViewType(position);
            }
            return TYPE_LIST_ITEM;
        }
        @Override
        public int getItemCount() {
            if(this.mAdapter != null){
                return getHeaderCount() + getFooterCount() + this.mAdapter.getItemCount();
            }else{
                return getHeaderCount() + getFooterCount();
            }
        }

        @Override
        public void registerAdapterDataObserver(AdapterDataObserver observer) {
            if(this.mAdapter != null){
                this.mAdapter.registerAdapterDataObserver(observer);
            }
        }

        @Override
        public void unregisterAdapterDataObserver(AdapterDataObserver observer) {
            if(this.mAdapter != null){
                this.mAdapter.unregisterAdapterDataObserver(observer);
            }
        }

        private class CustomViewHolder extends ViewHolder{

            public CustomViewHolder(View itemView) {
                super(itemView);
            }
        }
    }
}

使用方法github里也写的清清楚楚的

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private MyAdapter mAdapter;
private XCRecyclerView mRecyclerView;
private List<String> mData;
private View mHeaderView;
private View mFooterView;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mData = new  ArrayList<String>();
    for(int i = 0; i < 10 ;i++){
        mData.add("item_" + i);
    }
    mAdapter = new MyAdapter(mData);
    mRecyclerView = (XCRecyclerView) findViewById(R.id.recycler_view);
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    mHeaderView = LayoutInflater.from(this).inflate(R.layout.layout_header,mRecyclerView,false);
    mFooterView = LayoutInflater.from(this).inflate(R.layout.layout_footer,mRecyclerView,false);
    mRecyclerView.addHeaderView(mHeaderView);
    mRecyclerView.addFooterView(mFooterView);
    mRecyclerView.setAdapter(mAdapter);
}

注意点:

addHeaderView之后 列表的数据坐标即相应发生变化!即addHeadView一次,列表第一个数据的下坐标+1(0-->1)

adapter.notifyItemChanged();等方法的坐标类似,都要相应的变化。

比如你addHeadView()一次

那么你想更新列表第4个列表项的视图,则adapter.notifyItemChanged(3+1);  多加1  headView也算一个列表项。 

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-02-15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
未来汽车电子可能的变化?
目前的汽车有多达几十甚至上百个电子控制单元并连接到多种总线上,平均来说,目前的汽车大约采用25个ECU,但一些高端车型已经超过100个ECU。在过去,汽车电子电气架构一直遵循着“一个功能一个盒子”的分布式架构模式。如变速箱控制由TCU负责,发动机控制由EMS负责,虽这两个同样在动力域但分别由供应商提供各自的硬件和软件。在这样的汽车电子电气架构形式下,每增加一个功能,就需要动相应的控制器,涉及多方的交流和维护成本,进一步增加系统的复杂性和成本。最终会导致一个规模更大且复杂的车载网络和布线,也从另一方面影响整车的轻量化。
Defry
2022/04/19
7570
未来汽车电子可能的变化?
Level3及以上自动驾驶的汽车架构和开发模式变化
楼主基于自动驾驶应用场景分别从E/E架构、通讯方式、软件架构和流程标准等方面谈下与当前模式相比可能加强的方面和涉及的变化,当我扯淡,欢迎拍砖。
Defry
2022/04/19
8140
Level3及以上自动驾驶的汽车架构和开发模式变化
汽车电子架构 | 故事起源
近几十年来,汽车工业与电子技术的融合不断加深,催生了汽车产业链中的一个重要细分领域——汽车电子。
不惑
2024/04/12
3330
汽车电子架构 | 故事起源
汽车电子架构,进化或改革?
今天,汽车上数以百计的ECU(电子控制单元), MCU(微控制处理器单元)及其上面运行着的大量的嵌入式软件代码以及复杂的整车网络注定了汽车不同于其他的IOT设备和智能手机能够快速得追赶上信息技术发展的步伐。事实上汽车上的电子电气架构也一直在朝着为智能化体验服务这个方向在演化着,只是这个过程相比消费电子行业需要更长的时间。
曲奇泡芙
2019/08/16
1K0
汽车电子架构,进化或改革?
赋能车载数据服务器 - S32G域控制器芯片
近几天的CES 2020上,NXP公司发布了新一代的S32G车载网络处理器。作为NXP S32系列最新的处理器,S32G将汽车行业整车EE架构往高性能,分域架构的现代设计落地进一步推进。
曲奇泡芙
2020/02/14
8640
赋能车载数据服务器 - S32G域控制器芯片
基于tcl脚本语言的asic后端设计-软件定义汽车下的整车开发
  新一轮科技革命和产业变革方兴未艾,作为新技术集成应用最佳载体之一的汽车正加速向智能化转型,智能汽车已成为全球汽车产业发展的战略方向。整车电子系统功能复杂度呈指数级上升,软件占比持续增大。有数据显示,2010年主流车型约含1000万源代码行数,而2016年达到约1.5亿行。2018年软件约占D级车或大型乘用车整车价值的10%,据摩根士丹利估算,未来软件价值占比将达到60%左右。整车技术与工程核心正从传统硬件层面转移到软件,大众汽车表示,软件创新将占未来汽车创新的90%左右。
宜轩
2022/12/29
4200
畅想未来驾驶技术,汽车以太网势必先行
// 此处引用自度娘 // → ECU(Electronic Control Unit)电子控制单元,又称“行车电脑”、“车载电脑”等。从用途上讲则是汽车专用微机控制器。它和普通的电脑一样,由微处理器(CPU)、存储器(ROM、RAM)、输入/输出接口(I/O)、模数转换器(A/D)以及整形、驱动等大规模集成电路组成。用一句简单的话来形容就是“ECU就是汽车的大脑”。
鲜枣课堂
2019/07/22
4410
畅想未来驾驶技术,汽车以太网势必先行
Security Onboard Communication-SecOC
随着汽车电子的发展及整车功能复杂性的提高,车载控制器数量从之前的寥寥几个增加至规模复杂的上百个。基于功能的需求,各个控制器每时每刻需要进行大量数据的交互,数据交互的方式也多种多样,比如Lin、CAN、CANFD、FlexRay 、车载Ethernet等。
Defry
2022/04/19
1.1K0
Security Onboard Communication-SecOC
车载以太网(上)
车载以太网的出现背景楼主就不多做赘述了,其实主要是因汽车E/E架构和功能的复杂度提升而带来的对车辆数据传输带宽提高和通讯方式改变(基于服务的通讯-SOA)的需求。
Defry
2022/04/19
2.2K0
车载以太网(上)
TSN、智能驾驶和边缘计算有什么关系?
昨天,一则新闻在时间确定性网络群里刷屏了:创时科技开业,上汽智能驾驶又进关键一步。对于时间触发以太网和TTTech公司,笔者曾在文章一个人,一个想法,一家公司和即将被改变的全世界网络 一文中做过介绍,也预测把时间触发引入以太网将是未来网络的一个主要趋势。而上汽与TTTech公司的合作,则是TTTech公司打开国内市场的里程碑事件。
网络交换FPGA
2019/10/29
2.5K0
TSN、智能驾驶和边缘计算有什么关系?
车辆网络安全架构——安全通信协议
车载总线(Automotive Bus)是指在车辆内部用于不同电子控制单元(ECU)之间进行通信和数据传输的系统。它充当了车辆内部各个电子模块之间的数据传输媒介,使得不同的车辆系统可以相互协作和交换信息。
FB客服
2023/08/08
6520
车辆网络安全架构——安全通信协议
自动驾驶技术栈——常见概念篇
ECU全称是Electronic Control Unit。随着汽车电子设备的引入,汽车中很多机械组件逐渐改为汽车电子设备,导致ECU在新能源汽车中的占比越来越大。ECU在汽车电子中完成特定的控制功能,控制范围包括发动机,雨刷器,制动器等。
Coder-ZZ
2023/02/23
1.7K0
自动驾驶技术栈——常见概念篇
FlexRay 介绍
汽车上的总线技术包括:LIN、CAN、CAN FD、FlexRay、MOST及Ethernet,我们之前已经分享了LIN,CAN、CAN FD总线。在开始阅读之前,如果你对已介绍的总线技术还不了解的话,可以先阅读以下文章快速温习一下~
Defry
2022/04/19
9250
FlexRay 介绍
【ARM】ARM Cortex 处理器详细讲解
ARM Cortex处理器系列是ARM公司推出的一系列高性能、低功耗的处理器核心,广泛应用于不同类型的电子设备。Cortex处理器按应用需求分为三个主要系列:Cortex-A、Cortex-M和Cortex-R。以下是对这些系列的详细讲解。
LuckiBit
2024/12/11
7870
车载测试面试题实录
ADAS(Advanced Driver Assistance Systems,高级驾驶辅助系统)是一系列集成在现代汽车中的技术系统,旨在提高驾驶员的安全性、舒适性和便利性。这些系统使用传感器、处理器、控制器和算法来监测车辆周围的环境并提供驾驶员辅助。
周辰晨
2024/04/28
4150
特斯拉、华为们要用软件重新定义汽车?
“软件将占据未来汽车创新的90%。”在回复软件技术对未来汽车业究竟有多大时,大众汽车CEO赫伯特·迪斯如此说道,足见软件技术在这位世界知名汽车公司CEO心目中的分量。
刘旷
2022/07/14
2440
关于软件定义汽车的一些思考
19世纪最伟大发明是汽车,汽车的概念及其文化的发展是从蒸汽机的发明与应用开始的,回到汽车诞生的那个年代,在1879年卡尔.奔驰(K.Benz)试验成功一套二冲程发动机,并在1885年制造出世界上第一辆以汽油为动力的三轮汽车,至此第一台汽车诞生。
Defry
2022/04/19
4740
关于软件定义汽车的一些思考
三生三世 CPU,ISA 架构变迁
开发人员基于指令集架构(ISA),使用不同的处理器硬件实现方案,来设计不同性能的处理器,因此 ISA 又被视作 CPU 的灵魂。我们可以将指令集架构理解为一个抽象层,它是处理器底层硬件与运行在硬件上的软件之间桥梁和接口。
AI 电堂
2022/04/01
1.1K0
三生三世 CPU,ISA 架构变迁
ARM:Cortex-R82 低功耗存储主控设计
UFS(Universal Flash Storage)和eMMC(embedded MultiMediaCard)是两种常见的嵌入式闪存存储技术,广泛应用于智能手机、平板电脑和其他移动设备。
数据存储前沿技术
2025/02/11
990
ARM:Cortex-R82 低功耗存储主控设计
华为、百度、小米踏上造车新征程,软件如何吞噬汽车?
【编者按】在全行业线上化的今天,新一轮的技术变革从根本上动摇了传统汽车行业的百年游戏规则,并出现了以特斯拉、蔚来、小鹏等为代表的造车新势力,和以英伟达、百度、华为等为代表的技术赋能者。传统汽车企业如何应对才能拿到行业变革的门票,走上转型升级的道路? 本文精选自《新程序员·开发者黄金十年》,扫描底部小程序码或点击“阅读原文”可直接订阅。 作者 | 俞斌,联友科技CTO     出品 | 《新程序员》编辑部 从1885年德国人卡尔·本茨成功研发第一辆内燃机(ICE)汽车到今天,经过100多年的发展演变,汽车行
AI科技大本营
2023/05/08
2270
华为、百度、小米踏上造车新征程,软件如何吞噬汽车?
推荐阅读
相关推荐
未来汽车电子可能的变化?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档