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

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.lryc.cn/news/358446.html

相关文章:

  • Linux服务上MySQL的启动、重启和关闭
  • ctfshow web入门 嵌入式 bash cpp pwn
  • 【ONE·Git || 基本用法入门】
  • 【运维项目经历|021】Spark大数据分析平台建设项目
  • 装机数台,依旧还会心念i5-12600KF的性能和性价比优势:
  • Docker-----emqx部署
  • 三数之和-力扣
  • 2024 五月份国内外CTF 散装re 部分wp
  • [猫头虎分享21天微信小程序基础入门教程]第21天:小程序的社交分享与消息推送
  • aop整理
  • Sublime Text 基础教程(个人总结)
  • 线程安全 - 笔记
  • 分支机构多,如何确保文件跨域传输安全可控?
  • 长安链使用Golang编写智能合约教程(二)
  • jpom linux发布前端 ruoyi
  • K8S认证|CKA题库+答案| 15. 备份还原Etcd
  • 软件架构设计属性之一:功能性属性浅析
  • 学习Java的日子 Day48 函数,DOM
  • Scikit-Learn朴素贝叶斯
  • 网页设计步骤总结
  • 第十三期Big Demo Day亮点项目:CCarbon重塑碳交易生态,助力全球绿色发展
  • python基础知识总结(第一节)
  • DOS学习-目录与文件应用操作经典案例-comp
  • 原神抽卡点名程序教程(直接下载用)
  • gpt-4o继续迭代考场安排程序 一键生成考场清单
  • php 设置时区
  • ArcGIS不同图斑设置不同的透明度
  • 前端 CSS 经典:图片边框
  • 异常有什么,异常类有什么
  • 如何解压忘记了密码的加密zip压缩包?这两个方法收藏好!