首页 > 其他分享 >Android ListView 详解

Android ListView 详解

时间:2024-07-30 11:21:43浏览次数:10  
标签:students 视图 详解 convertView student position Android ListView public

Android ListView 详解

介绍

“List view” 是一种用户界面设计中的布局方式,它通过列表的形式展示信息,是一种将信息组织为条目(通常是行)的视图形式,每一项条目都是列表中的一行,可能包含文本、图像或其他元素。

基本使用

xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/listview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

activity

public class MainActivity extends AppCompatActivity {

    private ListView listView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        List<String> fruits =new ArrayList<>();

        fruits.add("苹果");
        fruits.add("香蕉");
        fruits.add("普通");
        fruits.add("西瓜");
        //为listview绑定控件
        listView =findViewById(R.id.listview);
        //为listview绑定适配器
        listView.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1,fruits));
    }
}

以上是最基本的使用方法

自定义适配器

现在使用listview来显示学生列表

entity

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    String name;
    String age;
    String sex;
    String image;
}
/*
@Data
@AllArgsConstructor
@NoArgsConstructor
这些注释需要添加依赖

    implementation 'org.projectlombok:lombok:1.18.20'
    annotationProcessor 'org.projectlombok:lombok:1.18.20'

如果不添加依赖自己写get、set方法也可以
*/

xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/listview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

为listview绘制适配界面

在layout目录下创建layout_student_list.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="match_parent"
    android:orientation="horizontal">
    <TextView
        android:id="@+id/name"
        android:layout_marginHorizontal="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/sex"
        android:layout_marginHorizontal="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/age"
        android:layout_marginHorizontal="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>

为listview创建适配器

public class MyListAdapter extends BaseAdapter {
    Context context;
    List<Student> students;

    public MyListAdapter(Context context, List<Student> students){
        //初始化
        this.context=context;
        this.students=students;
    }
    @Override
    public int getCount() {
        //返回list数量
        return students.size();
    }

    @Override
    public Object getItem(int position) {
        //获取每个item
        return students.get(position);
    }

    @Override
    public long getItemId(int position) {
        //获取下标
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // 使用 LayoutInflater 将 layout_student_list 布局文件转换为视图对象。
        View viewStudent = LayoutInflater.from(context).inflate(R.layout.layout_student_list, parent, false);
        //获得学生对象
        Student student = students.get(position);
        TextView name = viewStudent.findViewById(R.id.name);
        TextView age = viewStudent.findViewById(R.id.age);
        TextView sex = viewStudent.findViewById(R.id.sex);
        //将数据一一添加到布局中。
        name.setText(student.getName());
        age.setText(String.valueOf(student.getAge()));
        /*
       		age.setText();
       		TextView使用setText方法要使用字符串,非字符串会引发android.content.res.Resources$NotFoundException: String resource ID 异常
       		非字符串类型请先转为字符串
        */
        
        sex.setText(student.getSex());
        return viewStudent ;
    }
}

缺点

  1. 性能开销大:每次 getView 被调用时,findViewById 方法都会被调用,这会导致性能开销增加,特别是在长列表中。
  2. 视图查找开销:每次 getView 被调用时,都会查找视图组件,增加了 CPU 和内存开销。

使用ViewHolder 优化

使用ViewHolder 对ListView进行优化时只需要修改适配器MyListAdapter代码即可

public class MyListAdapter extends BaseAdapter {
    Context context;
    List<Student> students;

    public MyListAdapter(Context context, List<Student> students){
        this.context=context;
        this.students=students;
    }
    @Override
    public int getCount() {
        return students.size();
    }

    @Override
    public Object getItem(int position) {
        return students.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
         // 创建一个 ViewHolder 对象,用于缓存视图组件。
        ViewHolder viewHolder = null;
        //获得Item位置上的数据。
        Student student = students.get(position);
        if(convertView == null){
            convertView = LayoutInflater.from(context).inflate(R.layout.layout_student_list, parent, false);
        	// 创建一个新的 ViewHolder 实例,并将其与 convertView 关联。
            viewHolder = new ViewHolder(convertView);
        	// 将 ViewHolder 对象设置为 convertView 的标签,以便下次重用。
            convertView.setTag(viewHolder);
        }else{
        	// 如果 convertView 已经存在,则从 convertView 的标签中获取 ViewHolder 对象。
            viewHolder = (ViewHolder) convertView.getTag();
        }
        // 将当前学生的数据设置到视图中的相应组件。
        viewHolder.name.setText(student.getName());
        viewHolder.age.setText(String.valueOf(student.getAge()));
        viewHolder.sex.setText(student.getSex());
		// 返回最终的视图对象。
        return convertView;
    }

    static class ViewHolder{
    	// 定义用于缓存视图组件的变量。
        private final TextView name;
        private final TextView age;
        private final TextView sex;

        public ViewHolder(View itemView){ 
            // 在 itemView 中查找并初始化视图组件。
            name = itemView.findViewById(R.id.name);
            age = itemView.findViewById(R.id.age);
            sex = itemView.findViewById(R.id.sex);
        }
    }
}

优点:

  1. 性能优化:通过缓存视图组件,减少了频繁调用 findViewById 的次数,从而降低了 CPU 和内存开销。
  2. 更清晰的代码:代码更加简洁易懂,减少了在 getView 方法中重复的视图查找逻辑。
  3. 流畅的滚动体验:提高了 ListView 的滚动性能,使列表滚动更加流畅。

标签:students,视图,详解,convertView,student,position,Android,ListView,public
From: https://www.cnblogs.com/20lxj666/p/18331954

相关文章

  • Java代理模式详解
    Java代理模式详解概念代理模式是一种设计模式,为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。在Java中,代理模式主要分为静态代理和动态代理。静态代理静态......
  • 机器学习:详解是否要使用端到端的深度学习?(Whether to use end-to-end learning?)
    详解是否要使用端到端的深度学习?假设正在搭建一个机器学习系统,要决定是否使用端对端方法,来看看端到端深度学习的一些优缺点,这样就可以根据一些准则,判断的应用程序是否有希望使用端到端方法。这里是应用端到端学习的一些好处,首先端到端学习真的只是让数据说话。所以如果有足够多......
  • 使用 kivy 从 python 脚本的 buildozer 构建 android apk 时出错
    我想从使用kivy包构建的Python脚本构建apk为此,我使用googlecollab.这里是main.py脚本:importyoutube_dlfromkivy.appimportAppfromkivy.uix.boxlayoutimportBoxLayoutfromkivy.uix.buttonimportButtonfromkivy.uix.tex......
  • Dom-API | MutationObserver使用方法详解
    MutationObserver介绍MutationObserver是是一个用于监视DOM变动的WebAPI。通过它可以监控DOM树中的更改,比如元素的属性、子元素的增加和删除等,并在这些变化发生时执行回调函数。可以替代过时的MutationEvents,它具有更高的性能和更广的适用性。使用步骤详细说明1.创......
  • 两种常见排序(冒泡排序和选择排序)详解
    一、冒泡排序1.1、冒泡排序的原理讲解。例如有以下7个数的无序数列储存在数组arr[7]中,现在需要用冒泡排序法来对以下序列进行排序冒泡排序是比较相邻的两个数,如果第一个数比第二个数大,这两个数就要交换两个数的位置,如果第一个数小于第二个数则不用变换位置,例如第一个数3比......
  • android u开机流程详细分析(中) - zygote
    5、zygoteZygote进程是Android中所有Java进程的父进程。Zygote进程在Init进程启动过程中被以service服务的形式启动。从android5.0开始,android开始支持64位的编译,zygote本身也就有了32位和64位的区别,所以在这里用ro.zygote属性来控制启动不同版本的zygote进程。init.rc位于......
  • android 14开机流程详细分析(上) - Boot ROM,Boot loader,kernel,init
    androidu开机流程详细分析本文基于android-14.0.0_r2源码AOSP架构AOSP的软件堆栈包含以下层:图1.AOSP软件堆栈架构下面列出了图1中使用的术语的定义:Android应用完全使用AndroidAPI开发的应用。GooglePlay商店广泛用于查找和下载Android应用,不过也......
  • 青云——会话机制(详解)
    为什么会有这种会话机制        1.http协议是无状态的。也就是说每次与服务器进行连接,都必须重新发送请求。连接一次,请求一次。上次和这次的连接没有任何关系。底层的TCP连接会断开,用户的ip地址可能会发生变化。但是浏览器又需要记录访问者。        2.判断......
  • android studio 调用第三方无源代码so
    androidstudio调用第三方无源代码so在AndroidStudio中调用第三方无源码的SO(共享库),你需要遵循以下步骤:将SO文件放置在项目中合适的位置。配置app的build.gradle文件,确保Gradle在构建应用时知道SO文件的位置。在Java/Kotlin代码中使用JNI接口加载SO库。......
  • 并查集详解
    一、概念1.定义:并查集(英文:Disjoint-setdatastructure,直译为不交集数据结构)是一种数据结构,用于处理一些不交集(Disjointsets,一系列没有重复元素的集合)的合并及查询问题2.功能:并查集主要有两个功能。将两个元素添加到一个集合中。判断两个元素在不在同一个集合。3.作......