将多个 Adapter 数据合并到单个 ListView 中

将多个 adapter 数据合并到单个 listview 中

本文将介绍如何在 Android 应用中将多个不同数据源的数据整合到一个 ListView 中显示。通过创建一个自定义 Adapter,并使用不同的 ViewHolder 类型,可以有效地管理和展示来自不同 Adapter 的数据,从而实现灵活且统一的列表视图。

在 Android 开发中,有时我们需要将来自不同数据源的数据合并到一个 ListView 中显示。例如,在一个贷款申请页面,可能需要同时显示用户贷款申请列表和贷款信息列表。直接使用多个 Adapter 是不可行的,因为 ListView 只能设置一个 Adapter。解决此问题的一种有效方法是创建一个自定义 Adapter,并在该 Adapter 中处理不同类型的数据。

实现方法

创建数据模型类:

首先,定义代表不同数据类型的数据模型类。例如,LoanApplication 和 Loan。

public class LoanApplication {    // LoanApplication 相关的属性    private String applicationId;    private String applicationDate;    // ... 其他属性    public LoanApplication(String applicationId, String applicationDate) {        this.applicationId = applicationId;        this.applicationDate = applicationDate;    }    public String getApplicationId() {        return applicationId;    }    public String getApplicationDate() {        return applicationDate;    }}public class Loan {    // Loan 相关的属性    private String loanId;    private String loanAmount;    // ... 其他属性    public Loan(String loanId, String loanAmount) {        this.loanId = loanId;        this.loanAmount = loanAmount;    }    public String getLoanId() {        return loanId;    }    public String getLoanAmount() {        return loanAmount;    }}

创建自定义 Adapter:

创建一个自定义 Adapter,该 Adapter 负责管理来自不同数据源的数据。 在该 Adapter 中,需要定义不同的 ViewHolder 类型,对应于不同的数据模型。

import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;import java.util.List;public class CombinedAdapter extends BaseAdapter {    private Context context;    private List dataList; // 使用 Object 存储不同类型的数据    private LayoutInflater inflater;    private static final int TYPE_LOAN_APPLICATION = 0;    private static final int TYPE_LOAN = 1;    public CombinedAdapter(Context context, List dataList) {        this.context = context;        this.dataList = dataList;        this.inflater = LayoutInflater.from(context);    }    @Override    public int getCount() {        return dataList.size();    }    @Override    public Object getItem(int position) {        return dataList.get(position);    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public int getItemViewType(int position) {        Object item = dataList.get(position);        if (item instanceof LoanApplication) {            return TYPE_LOAN_APPLICATION;        } else if (item instanceof Loan) {            return TYPE_LOAN;        } else {            return -1; // 或者抛出异常,处理未知类型        }    }    @Override    public int getViewTypeCount() {        return 2; // 两种类型:LoanApplication 和 Loan    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        ViewHolderLoanApplication loanApplicationHolder = null;        ViewHolderLoan loanHolder = null;        int type = getItemViewType(position);        if (convertView == null) {            switch (type) {                case TYPE_LOAN_APPLICATION:                    convertView = inflater.inflate(R.layout.item_loan_application, parent, false);                    loanApplicationHolder = new ViewHolderLoanApplication();                    loanApplicationHolder.applicationIdTextView = convertView.findViewById(R.id.applicationIdTextView);                    loanApplicationHolder.applicationDateTextView = convertView.findViewById(R.id.applicationDateTextView);                    convertView.setTag(loanApplicationHolder);                    break;                case TYPE_LOAN:                    convertView = inflater.inflate(R.layout.item_loan, parent, false);                    loanHolder = new ViewHolderLoan();                    loanHolder.loanIdTextView = convertView.findViewById(R.id.loanIdTextView);                    loanHolder.loanAmountTextView = convertView.findViewById(R.id.loanAmountTextView);                    convertView.setTag(loanHolder);                    break;            }        } else {            switch (type) {                case TYPE_LOAN_APPLICATION:                    loanApplicationHolder = (ViewHolderLoanApplication) convertView.getTag();                    break;                case TYPE_LOAN:                    loanHolder = (ViewHolderLoan) convertView.getTag();                    break;            }        }        Object item = dataList.get(position);        switch (type) {            case TYPE_LOAN_APPLICATION:                LoanApplication loanApplication = (LoanApplication) item;                loanApplicationHolder.applicationIdTextView.setText(loanApplication.getApplicationId());                loanApplicationHolder.applicationDateTextView.setText(loanApplication.getApplicationDate());                break;            case TYPE_LOAN:                Loan loan = (Loan) item;                loanHolder.loanIdTextView.setText(loan.getLoanId());                loanHolder.loanAmountTextView.setText(loan.getLoanAmount());                break;        }        return convertView;    }    static class ViewHolderLoanApplication {        TextView applicationIdTextView;        TextView applicationDateTextView;    }    static class ViewHolderLoan {        TextView loanIdTextView;        TextView loanAmountTextView;    }}

ViewHolder 定义:

为每种数据类型定义一个 ViewHolder 类,用于缓存 View,提高 ListView 的性能。

AI帮个忙 AI帮个忙

多功能AI小工具,帮你快速生成周报、日报、邮、简历等

AI帮个忙 55 查看详情 AI帮个忙

static class ViewHolderLoanApplication {    TextView applicationIdTextView;    TextView applicationDateTextView;}static class ViewHolderLoan {    TextView loanIdTextView;    TextView loanAmountTextView;}

布局文件:

为每种数据类型创建对应的布局文件(例如 item_loan_application.xml 和 item_loan.xml)。

item_loan_application.xml:

        

item_loan.xml:

        

组装数据并设置 Adapter:

将不同数据源的数据添加到同一个 List 中,然后将该 List 传递给自定义 Adapter。

List combinedList = new ArrayList();// 假设 customerLoanApplicationList 和 customerLoanList 分别是 LoanApplication 和 Loan 类型的 ListcombinedList.addAll(customerLoanApplicationList);combinedList.addAll(customerLoanList);CombinedAdapter adapter = new CombinedAdapter(this, combinedList);binding.listLoan.setAdapter(adapter);

注意事项:

getItemViewType() 方法用于确定列表中每个 item 的类型。getViewTypeCount() 方法返回 Adapter 中不同类型的数量。在 getView() 方法中,根据 item 类型,使用不同的 ViewHolder 和布局文件。使用 Object 作为 dataList 的类型,可以存储不同类型的数据。确保为每种数据类型创建相应的布局文件。

总结

通过创建自定义 Adapter 并使用不同的 ViewHolder 类型,可以将来自不同数据源的数据合并到一个 ListView 中显示。这种方法可以有效地管理和展示来自不同 Adapter 的数据,从而实现灵活且统一的列表视图。 虽然此示例使用了 ListView,但更推荐使用 RecyclerView,因为它提供了更好的性能和灵活性,尤其是在处理大量数据时。 RecyclerView 的 ViewHolder 模式可以更有效地复用 View,从而提高滚动性能。 使用 RecyclerView 的方法与上述类似,只是需要将 BaseAdapter 替换为 RecyclerView.Adapter,并使用 RecyclerView.ViewHolder。

以上就是将多个 Adapter 数据合并到单个 ListView 中的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/344707.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月5日 19:50:51
下一篇 2025年11月5日 19:53:52

相关推荐

  • Golang select多路复用实战项目

    答案:select实现多路复用,监听消息、订阅、超时与中断事件。通过select在广播系统中处理消息分发、客户端加入/退出、超时控制和信号中断,嵌套非阻塞发送避免阻塞,最终实现高效并发的消息广播服务。 在Go语言中,select 是实现多路复用的核心机制,常用于处理多个通道的并发操作。它类似于 sw…

    2025年12月16日
    000
  • 如何使用Golang实现状态机模式管理状态

    状态机模式通过接口和结构体在Golang中实现对象行为随状态变化的管理。1. 定义State接口声明进入、执行、退出方法;2. Context结构体持有当前状态并委托请求;3. 每个具体状态如IdleState、RunningState实现State接口;4. 状态切换通过Context的Switc…

    2025年12月16日
    000
  • Golang结构体标签读取与自定义校验示例

    答案:Go语言通过结构体标签结合反射实现字段校验,如validate:”required”用于定义规则,反射读取标签并执行自定义逻辑,示例中Name不能为空、Age需≥18,输出相应错误提示。 在Go语言中,结构体标签(Struct Tags)是一种为结构体字段附加元信息的机…

    2025年12月16日
    000
  • 如何在Golang中使用reflect进行类型判断

    在Golang中,reflect 包提供了运行时反射能力,可以动态获取变量的类型和值。进行类型判断是反射的常见用途之一。下面介绍如何使用 reflect 正确、高效地判断类型。 1. 使用 reflect.TypeOf 判断基础类型 reflect.TypeOf 返回一个 Type 接口,表示变量的…

    2025年12月16日
    000
  • Go语言实现服务器优雅重启:保持连接不中断的策略与实践

    本文深入探讨Go语言服务器如何实现优雅重启,确保在服务升级或配置变更时现有连接不中断,从而提供零停机时间的用户体验。我们将阐述其核心机制,包括文件描述符的继承与传递,以及Go标准库中net.FileListener和os.StartProcess等关键组件的应用,并提供实现步骤与注意事项。 什么是优…

    2025年12月16日
    000
  • Golang类型断言语法与接口使用技巧

    接口与类型断言用于实现Go语言的多态与类型安全操作。接口定义方法集,任何实现这些方法的类型自动满足该接口;空接口interface{}可存储任意类型值,常用于不确定类型的场景。使用类型断言value, ok := interfaceVar.(ConcreteType)可安全提取具体类型,避免pani…

    2025年12月16日
    000
  • Golang数据类型语法与转换技巧

    Go语言要求显式类型转换,基本类型包括整型、浮点型、布尔型和字符串,变量可用var或:=声明;数值与字符串转换需用strconv包,字节切片与字符串可直接转换但字符串不可变;接口类型通过类型断言获取具体值,type switch处理多类型,确保类型安全。 Go语言的数据类型设计简洁且高效,掌握其语法…

    2025年12月16日
    000
  • Go语言与OpenGL:解决跨线程调用导致的问题

    本文探讨了Go语言中将OpenGL图形渲染集成到并发程序时可能遇到的线程限制问题。由于OpenGL等图形库通常要求所有相关操作在同一OS线程上执行,Go的goroutine调度机制可能导致渲染异常和程序卡顿。解决方案是利用runtime.LockOSThread()将主goroutine锁定到OS主…

    2025年12月16日
    000
  • Golang flag命令行参数解析实践

    Go语言flag包支持命令行参数解析,提供字符串、整型、布尔等类型处理及帮助信息生成。通过flag.String、flag.Int等函数定义参数,使用flag.Parse()解析,支持指针返回和变量绑定两种方式。可利用flag.Bool定义布尔参数,注意-flag与-flag=true等效。复杂工具…

    2025年12月16日
    000
  • 解决Go语言OpenGL/SDL应用中的Goroutine线程亲和性问题

    本文探讨了Go语言Goroutine调度机制与OpenGL/SDL等图形库对主线程的严格要求之间的冲突。当Goroutine在不同OS线程间切换时,可能导致图形渲染异常。教程将详细介绍如何利用runtime.LockOSThread将关键图形操作绑定到主OS线程,并通过一个任务队列模式,有效解决线程…

    2025年12月16日
    000
  • Go语言PNG图像通道互换:深入解析image包的颜色处理与实践

    本教程探讨如何在Go语言中对PNG图像的颜色通道进行互换。针对image.Image接口的特性,文章介绍了两种核心策略:一是通过自定义接口实现通用的像素设置,并详细讲解uint32颜色值到uint8的转换;二是通过类型断言直接操作*image.RGBA类型,实现更高效的通道交换。教程将提供完整的代码…

    2025年12月16日
    000
  • Golang 文件IO错误处理与异常恢复示例

    Go语言通过返回error类型显式处理文件IO错误,结合defer确保资源释放,使用fmt.Errorf包装错误信息,并可借助defer和recover捕获panic实现异常恢复;需针对os.ErrNotExist、os.ErrPermission等不同错误类型采取相应处理策略,提升程序健壮性。 在…

    2025年12月16日
    000
  • Golang图像处理:深度解析PNG通道交换技术

    本文深入探讨了在Go语言中如何使用image和image/png包对PNG图像的颜色通道进行交换。我们将从image.Image接口的限制入手,逐步介绍两种核心的像素修改方法:通过自定义ImageSet接口进行通用像素操作,以及针对*image.RGBA类型的优化处理。文章将提供详细的代码示例,涵盖…

    2025年12月16日
    000
  • Golang Web表单数据序列化与处理

    答案:Go语言通过net/http包解析表单数据,支持自动映射到结构体。使用r.ParseForm()处理普通表单,r.FormValue获取参数,结合反射实现结构体绑定,提升代码可维护性。 在Go语言开发Web应用时,处理前端提交的表单数据是常见需求。Golang标准库提供了简洁而高效的方式进行表…

    2025年12月16日
    000
  • Golang使用panic处理不可恢复错误方法

    panic用于处理不可恢复错误,如初始化失败、系统资源不可用等,通过panic()触发并可由defer中的recover捕获以防止程序崩溃,但应避免在公共API中滥用,普通错误需返回error而非panic。 在Go语言中,panic用于处理程序无法继续执行的严重错误,也就是不可恢复的错误。它会中断…

    2025年12月16日
    000
  • Go语言中PNG图像通道交换的实现教程

    本文详细介绍了在Go语言中如何读取PNG图像、访问像素颜色信息并交换其颜色通道。文章探讨了两种主要方法:通过自定义接口处理通用的image.Image类型以设置像素,以及通过类型断言直接操作*image.RGBA类型图像。教程提供了完整的代码示例,并强调了处理颜色通道值时的注意事项,旨在帮助开发者高…

    2025年12月16日
    000
  • Golang接口语法基础与实现技巧

    Go接口通过隐式实现定义行为,提升代码灵活性;合理使用小接口、空接口及类型断言可增强可测试性与扩展性,注意接收者类型选择以避免实现错误。 Go语言中的接口(interface)是一种定义行为的方式,它让类型可以通过实现方法来满足接口,从而实现多态。接口不是具体的数据结构,而是对“能做什么”的抽象。理…

    2025年12月16日
    000
  • Golang常见运行时错误类型分析与解决

    空指针解引用因访问nil指针引发panic,需初始化指针或判空处理。2. 切片越界由索引超出长度导致,应校验边界或用range遍历。3. 并发访问map触发fatal error,需用sync.RWMutex、sync.Map或channel保证安全。4. 类型断言失败致panic,应使用v, ok…

    2025年12月16日
    000
  • Golang自定义错误类型实现与应用示例

    自定义错误类型通过实现error接口提供更清晰的上下文和灵活控制,如定义结构体MyError并实现Error方法,结合工厂函数简化创建,在业务逻辑中使用errors.As进行类型判断,利用%w包装错误以保留调用链,提升错误处理的结构化与可维护性。 在Go语言中,错误处理是程序设计的重要组成部分。虽然…

    2025年12月16日
    000
  • Go语言中 select 语句的非阻塞处理:避免 default 的陷阱

    本文旨在深入解析Go语言中 select 语句的 default 用法,并阐述其可能导致的阻塞问题。通过具体示例,我们将分析为何在没有就绪的 channel 时,空的 default 分支会导致程序无法响应其他 channel 事件。此外,本文还将介绍几种避免阻塞的方案,并强调在并发编程中,合理利用…

    2025年12月16日
    000

发表回复

登录后才能评论
关注微信