Android 自定义Adapter关键函数getView性能最优使用

文章目录

    • 1、自定义Adapter关键函数`getView()`标准写法
    • 2、布局文件`list_item_user.xml`
    • 3、解释
    • 3、示例使用
    • 4、结果
    • 5、进一步优化和扩展
      • 5.1. **优化性能:ViewHolder模式**
      • 5.2. **处理多种类型的视图**
      • 5.3. **使用RecyclerView.Adapter**
    • 6、RecyclerView使用示例
    • 7、结果
    • 8、结论

在Android开发中,自定义Adapter是非常常见的,用于为ListView、GridView、RecyclerView等视图提供数据。自定义Adapter的关键函数是 getView()方法,它负责为每一项数据创建和返回一个View。以下是一个标准的自定义Adapter及其 getView()方法的详细用例和解释。

1、自定义Adapter关键函数getView()标准写法

假设我们有一个简单的用户数据类:

public class User {private String name;private String email;public User(String name, String email) {this.name = name;this.email = email;}public String getName() {return name;}public String getEmail() {return email;}
}

自定义Adapter的实现:

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 UserAdapter extends BaseAdapter {private Context context;private List<User> userList;private LayoutInflater inflater;public UserAdapter(Context context, List<User> userList) {this.context = context;this.userList = userList;this.inflater = LayoutInflater.from(context);}@Overridepublic int getCount() {return userList.size();}@Overridepublic Object getItem(int position) {return userList.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder viewHolder;if (convertView == null) {// Inflate the custom layoutconvertView = inflater.inflate(R.layout.list_item_user, parent, false);// Initialize the ViewHolderviewHolder = new ViewHolder();viewHolder.nameTextView = convertView.findViewById(R.id.nameTextView);viewHolder.emailTextView = convertView.findViewById(R.id.emailTextView);// Store the holder with the viewconvertView.setTag(viewHolder);} else {// Retrieve the view holderviewHolder = (ViewHolder) convertView.getTag();}// Get the current userUser currentUser = (User) getItem(position);// Set the user details to the viewviewHolder.nameTextView.setText(currentUser.getName());viewHolder.emailTextView.setText(currentUser.getEmail());return convertView;}// ViewHolder pattern to optimize list view performancestatic class ViewHolder {TextView nameTextView;TextView emailTextView;}
}

2、布局文件list_item_user.xml

这是自定义的布局文件,定义了每个列表项的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"android:padding="8dp"><TextViewandroid:id="@+id/nameTextView"android:layout_width="match_parent"android:layout_height="wrap_content"android:textSize="16sp"android:textColor="@android:color/black" /><TextViewandroid:id="@+id/emailTextView"android:layout_width="match_parent"android:layout_height="wrap_content"android:textSize="14sp"android:textColor="@android:color/darker_gray" /></LinearLayout>

3、解释

  1. ViewHolder模式

    • ViewHolder是一个静态内部类,用来缓存View。这样避免了每次调用getView()方法时都调用findViewById()方法,提高了ListView的性能。
  2. getView()方法

    • convertView参数是用于重用旧视图的。为了性能优化,如果convertView不为null,则可以重用。
    • 如果convertView为null,意味着这是第一次创建这个视图,需要使用LayoutInflater去加载布局,并初始化ViewHolder
    • 使用convertView.setTag(viewHolder)来存储ViewHolder对象,方便后续重用。
    • 使用convertView.getTag()来获取缓存的ViewHolder对象,避免重复调用findViewById()
    • 最后,将当前项的数据设置到ViewHolder中的各个控件上。

3、示例使用

假设在某个Activity中使用这个Adapter:

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ListView listView = findViewById(R.id.listView);// 示例数据List<User> users = new ArrayList<>();users.add(new User("Alice", "alice@example.com"));users.add(new User("Bob", "bob@example.com"));// 设置自定义AdapterUserAdapter adapter = new UserAdapter(this, users);listView.setAdapter(adapter);}
}

4、结果

运行应用时,ListView将显示用户列表,每行包含用户名和电子邮件地址。通过使用ViewHolder模式,确保了列表的高效滚动和视图重用。

5、进一步优化和扩展

5.1. 优化性能:ViewHolder模式

在大数据集的情况下,ViewHolder模式是非常重要的优化技术。它通过缓存View引用,减少了不必要的视图查找操作。

// Adapter类中
@Override
public View getView(int position, View convertView, ViewGroup parent) {ViewHolder viewHolder;if (convertView == null) {// Inflate the custom layoutconvertView = inflater.inflate(R.layout.list_item_user, parent, false);// Initialize the ViewHolderviewHolder = new ViewHolder();viewHolder.nameTextView = convertView.findViewById(R.id.nameTextView);viewHolder.emailTextView = convertView.findViewById(R.id.emailTextView);// Store the holder with the viewconvertView.setTag(viewHolder);} else {// Retrieve the view holderviewHolder = (ViewHolder) convertView.getTag();}// Get the current userUser currentUser = (User) getItem(position);// Set the user details to the viewviewHolder.nameTextView.setText(currentUser.getName());viewHolder.emailTextView.setText(currentUser.getEmail());return convertView;
}// ViewHolder pattern to optimize list view performance
static class ViewHolder {TextView nameTextView;TextView emailTextView;
}

5.2. 处理多种类型的视图

有时我们需要在一个列表中展示不同类型的视图,可以通过覆盖getViewTypeCount()getItemViewType(int position)来实现。

@Override
public int getViewTypeCount() {// 两种不同的视图类型return 2;
}@Override
public int getItemViewType(int position) {User user = (User) getItem(position);if (user.isSpecialUser()) {return 0; // 特殊用户类型} else {return 1; // 普通用户类型}
}@Override
public View getView(int position, View convertView, ViewGroup parent) {int viewType = getItemViewType(position);ViewHolder viewHolder;if (convertView == null) {switch (viewType) {case 0:// 特殊用户视图convertView = inflater.inflate(R.layout.special_user_item, parent, false);viewHolder = new SpecialViewHolder();viewHolder.specialTextView = convertView.findViewById(R.id.specialTextView);break;case 1:// 普通用户视图convertView = inflater.inflate(R.layout.list_item_user, parent, false);viewHolder = new ViewHolder();viewHolder.nameTextView = convertView.findViewById(R.id.nameTextView);viewHolder.emailTextView = convertView.findViewById(R.id.emailTextView);break;}convertView.setTag(viewHolder);} else {viewHolder = (ViewHolder) convertView.getTag();}// 填充数据User currentUser = (User) getItem(position);if (viewType == 0) {((SpecialViewHolder) viewHolder).specialTextView.setText(currentUser.getSpecialInfo());} else {viewHolder.nameTextView.setText(currentUser.getName());viewHolder.emailTextView.setText(currentUser.getEmail());}return convertView;
}// 普通ViewHolder
static class ViewHolder {TextView nameTextView;TextView emailTextView;
}// 特殊用户ViewHolder
static class SpecialViewHolder extends ViewHolder {TextView specialTextView;
}

5.3. 使用RecyclerView.Adapter

如果你的项目使用RecyclerView,而不是ListView或GridView,可以使用RecyclerView.Adapter来实现自定义Adapter。RecyclerView比ListView更强大和灵活,并且内置了ViewHolder模式。

public class UserAdapter extends RecyclerView.Adapter<UserAdapter.UserViewHolder> {private List<User> userList;public UserAdapter(List<User> userList) {this.userList = userList;}@Overridepublic UserViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_user, parent, false);return new UserViewHolder(itemView);}@Overridepublic void onBindViewHolder(UserViewHolder holder, int position) {User currentUser = userList.get(position);holder.nameTextView.setText(currentUser.getName());holder.emailTextView.setText(currentUser.getEmail());}@Overridepublic int getItemCount() {return userList.size();}public static class UserViewHolder extends RecyclerView.ViewHolder {public TextView nameTextView;public TextView emailTextView;public UserViewHolder(View view) {super(view);nameTextView = view.findViewById(R.id.nameTextView);emailTextView = view.findViewById(R.id.emailTextView);}}
}

6、RecyclerView使用示例

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);RecyclerView recyclerView = findViewById(R.id.recyclerView);// 示例数据List<User> users = new ArrayList<>();users.add(new User("Alice", "alice@example.com"));users.add(new User("Bob", "bob@example.com"));// 设置布局管理器recyclerView.setLayoutManager(new LinearLayoutManager(this));// 设置自定义AdapterUserAdapter adapter = new UserAdapter(users);recyclerView.setAdapter(adapter);}
}

7、结果

在使用RecyclerView时,列表项的视图会更高效地被管理和重用,提供更平滑的滚动体验。

8、结论

无论是ListView还是RecyclerView,自定义Adapter的getView()方法(或onBindViewHolder()方法)都是核心部分,负责创建和绑定视图。使用ViewHolder模式可以显著提高性能。对于复杂的列表,可以通过实现不同的视图类型来满足需求。RecyclerView提供了更灵活和高效的实现,推荐在新的项目中使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/839549.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DOS学习-目录与文件应用操作经典案例-del

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一.前言 二.使用 三.案例 一.前言 DOS系统的del命令是一个用于删除文件的命令行工具。以下…

使用公共Wi-Fi所面临的风险有哪些

尽量不要使用公共wifi做转账、支付、修改密码等金融性或私密性的操作。公共Wi-Fi网络存在许多风险。尽管商家可能认为他们为顾客提供了一个有价值的服务&#xff0c;很多人也认为在星巴克噼里啪啦的乱敲键盘非常小资&#xff0c;但其实这些网络的安全性可能存在极大的漏洞&…

【sass插值语句 #{}简介以及使用方法】

Sass 中的插值&#xff08;Interpolation&#xff09;是一种强大的特性&#xff0c;它允许你在 Sass 代码中嵌入变量、选择器、属性名或任何其他 Sass 表达式&#xff0c;并动态地生成 CSS 代码。插值通过 #{} 语法来实现。 Sass 插值简介 Sass 插值允许你创建可动态生成内容…

安卓12aosp mtp屏蔽内部存储显示,只展示特定文件夹和文件类型

系统&#xff1a;安卓12 屏蔽sd卡/内存存储显示 packages/services/Mtp/src/com/android/mtp/MtpService.java 修改如下&#xff0c;屏蔽了内部存储&#xff0c;如果需要屏蔽sd卡也可以根据这里做修改&#xff1a; private void addStorage(StorageVolume volume) {Log.v(TAG,…

[GStreamer] gst_element_link 及 pad 在继承体系中如何存在

前言&#xff1a; pad 是每个 element实例 都有的&#xff0c;是 elemenet 之间沟通的代理人&#xff0c;没有 pad 的 element 没法于其他element交流。 考虑到gstreamer存在继承体系&#xff0c;那么如果继承类element不在init函数里创建pad&#xff0c;那么在gst_element_l…

51打开工程,发现cannot read project file问题

解决办法&#xff1a; 1、路径太长&#xff0c;可以在桌面重新创建一个文件夹&#xff0c;把所有的文件都移动到新的文件夹中 2、创建工程的时候&#xff0c;都勾选上&#xff0c;就没问题

OracleDG原理

一、DataGuard架构介绍 1、基本介绍 在DG环境中&#xff0c;至少会有两个数据库&#xff0c;一个数据库处于Open状态&#xff0c;对外提供服务&#xff0c;这个数据库叫做primary Database。第二个数据库处于恢复状态&#xff0c;叫做Standby Database。运行时Primay Databas…

vue从入门到精通(四):MVVM模型

一,MVVM MVVM&#xff08;Model–view–viewmodel&#xff09;是一种软件架构模式。MVVM有助于将图形用户界面的开发与业务逻辑或后端逻辑&#xff08;数据模型&#xff09;的开发分离开来。详见MVVM 二,Vue中的MVVM Vue虽然没有完全遵循 MVVM 模型&#xff0c;但是 Vue 的设…

手机相册怎么恢复?如何挽救误删的照片?

手机相册成为我们存储和分享照片的主要途径&#xff0c;这些照片可能代表着我们的美好回忆、重要时刻或珍贵的瞬间。然而&#xff0c;有时候我们会因为误操作或一时冲动&#xff0c;将一些珍贵的照片误删&#xff0c;并且很难找回来。手机相册怎么恢复呢&#xff1f;本文将为你…

基于Tensorflow+Keras的卷积神经网络(CNN)人脸识别

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景与意义 人脸识别是计算机视觉领域的一个重要研究方向&#xff0c;广泛应用于安全监控、身份验证、人机…

Android 性能为王时代SparseArray和HashMap一争高下

文章目录 一、SparseArray 源码分析1. **类定义和构造函数**2. **基本方法**2.1 put(int key, E value)2.2 get(int key)2.3 delete(int key)2.4 removeAt(int index)2.5 gc()2.6 size()2.7 keyAt(int index) 和 valueAt(int index) 3. **辅助方法**3.1 binarySearch() 二、使用…

最新AI智能问答创作系统ChatGPT网站源码V4.20版本,GPTs、AI绘画、AI换脸、垫图混图+(GoMaxAI系统搭建部署教程文档)

Midjourney&#xff08;人工智能图像生成器&#xff09;&#xff0c;仅用了一年时间就已经火爆全球。它就像是一个想象力的助力器&#xff0c;总能带给人们一些不可思议的奇妙的作品。Midjourney虽然是一款最强的AI绘画工具&#xff0c;但对于很多人来说Midjourney怎么用&#…

使用JavaScript日历小部件和DHTMLX Gantt的应用场景(三)

DHTMLX Suite UI 组件库允许您更快地构建跨平台、跨浏览器 Web 和移动应用程序。它包括一组丰富的即用式 HTML5 组件&#xff0c;这些组件可以轻松组合到单个应用程序界面中。 DHTMLX Gantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表&#xff0c;可满足项目管理应用…

匝间冲击耐压试验仪产品介绍及工作原理

产品简介 武汉凯迪正大KD2684S匝间冲击耐压试验仪适用于电机、变压器、电器线圈等这些由漆包线绕制的产品。因漆包线的绝缘涂敷层本身存在着质量问题&#xff0c;以及在绕线、嵌线、刮线、接头端部整形、绝缘浸漆、装配等工序工艺中不慎而引起绝缘层的损伤等&#xff0c;都会造…

在线投票系统源码 网上投票平台创建 安全稳定 支持自定义投票规则+礼物道具功能

分享一款在线投票系统源码&#xff0c;是一款功能丰富、安全稳定的网络投票平台解决方案。通过本源码&#xff0c;用户可以轻松创建并管理各种在线投票活动&#xff0c;支持自定义投票规则&#xff0c;同时集成礼物道具功能&#xff0c;增强用户参与度和投票活动的趣味性&#…

2024 年 电工杯(B题)大学生数学建模挑战赛 | 平衡膳食食谱 | 数学建模完整代码+建模过程全解全析

当大家面临着复杂的数学建模问题时&#xff0c;你是否曾经感到茫然无措&#xff1f;作为2022年美国大学生数学建模比赛的O奖得主&#xff0c;我为大家提供了一套优秀的解题思路&#xff0c;让你轻松应对各种难题。 CS团队倾注了大量时间和心血&#xff0c;深入挖掘解决方案。通…

常用的框架——— Android UtilCode

AndroidUtilCode是一个功能强大且易于使用的Android库。该库封装了Android开发中经常使用的具备完整演示和单元测试的功能。经过使用其封装的API&#xff0c;能够大大提升开发效率。该程序主要由两个模块组成&#xff0c;utilcode&#xff08;一般在开发中使用&#xff09;和su…

【真人Q版手办风】线稿手绘+ AI绘图 Stable Diffusion 完整制作过程分享

大家好&#xff0c;我是设计师阿威。 今天给大家分享一篇【真人Q版卡通手办】风格的制作过程&#xff0c;话不多说&#xff0c;进入正题。 成品预览 手绘线稿 首先&#xff0c;我使用的是老款手绘软件【SAI】&#xff0c;用[钢笔工具]进行了人物的线稿Q版描绘。&#x1f447…

ArcEngine/ArcObject转换影像解决偏色的问题IRasterLayer

IRasterLayer里面的Renderer使用RasterRGBRendererClass&#xff0c;StretchType设置为NONE。以下是我将图像转换为img格式&#xff0c;采用RLE无损压缩。 IRasterLayer rasterLayer new RasterLayerClass(); rasterLayer.CreateFromFilePath(strFromName); IRaster pRaster …

巨控无线通讯模块在煤化工皮带保护系统中的应用

一、项目介绍 近年来由于煤矿化工行业在实际生产过程中事故频发&#xff0c;国家安监部门自2022年起开展了为其三年的专项整治行动&#xff0c;皮带运输系统作为煤矿化工行业自动化系统的重要组成部分成为此次专项整治重点。 兖矿新疆能化有限公司作为山能集团在新疆分部的龙…