Android入门之实现自定义Adapter

当我们在Android应用程序中使用ListView、GridView等控件时,经常需要实现自定义的Adapter。本文就是为了让大家了解实现自定义Adapter的一些技巧。

前置知识

在开始实现自定义Adapter之前,需要掌握以下关键概念:

  • ListView或GridView:Android中列表控件,要显示数据时需要一个ListView或GridView控件。
  • Adapter:处理数据源和界面交互的桥梁,实现其中的方法可以控制ListView或GridView中的显示内容。
  • ViewHolder:缓存ListView或GridView中每一项的View中的控件,提高列表的滑动效率。

实现自定义Adapter步骤

在Android中实现自定义Adapter大致可以分为以下步骤:

1. 定义数据源

在开发中需要定义一些数据模型来获取和存储数据,这些模型可以定义为Java类,包括需要展示的信息等。

示例:定义一个Student类。

public class Student {
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

2. 实现Adapter

定义自定义Adapter需要继承于BaseAdapter,实现其中的方法。

示例:定义一个StudentAdapter类。

public class StudentAdapter extends BaseAdapter {
    private List<Student> studentList;
    private LayoutInflater layoutInflater;

    public StudentAdapter(Context context, List<Student> studentList) {
        this.studentList = studentList;
        this.layoutInflater = LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
        return studentList.size();
    }

    @Override
    public Student getItem(int position) {
        return studentList.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;
        if (convertView == null) {
            convertView = layoutInflater.inflate(R.layout.item_student, parent, false);
            viewHolder = new ViewHolder();
            viewHolder.tvName = convertView.findViewById(R.id.tv_name);
            viewHolder.tvAge = convertView.findViewById(R.id.tv_age);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        Student student = getItem(position);
        viewHolder.tvName.setText(student.getName());
        viewHolder.tvAge.setText(String.valueOf(student.getAge()));
        return convertView;
    }

    private class ViewHolder {
        TextView tvName;
        TextView tvAge;
    }
}

在上面的示例中,需要重写BaseAdapter中的以下几个方法:

  • getCount():获取ListView或GridView的数量。
  • getItem(int position):获取一项Item的数据。
  • getItemId(int position):获取一项Item的ID,如果该项Item都是同样ID可以使用position作为ID。
  • getView(int position, View convertView, ViewGroup parent):这个方法用来设置列表的各项属性的,比如文本、图片等。

需要注意的是,在getView方法中,需要判断是否获取到缓存的ViewHolder,如果没有则需要创建一个ViewHolder并缓存起来。

3. 设置Adapter

在Activity中,需要使用ListView或者GridView控件,然后设置Adapter。

示例:在MainActivity中设置ListView。

public class MainActivity extends AppCompatActivity {
    private ListView lvStudent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lvStudent = findViewById(R.id.lv_student);
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("李四", 20));
        StudentAdapter studentAdapter = new StudentAdapter(this, studentList);
        lvStudent.setAdapter(studentAdapter);
    }
}

在上面的示例中,首先要获取一个ListView控件,然后创建一个装有Student对象的List,接着实例化一个自定义Adapter并设置到ListView控件中。

4. 实现具体列表项布局

最后一步非常简单,就是定义自己需要的列表项的布局和控件,比如下面这个示例中自定义了一个item_student.xml布局,设置了内部的TextView控件来展示学生的姓名和年龄。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#666666"
        android:textSize="18sp"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="10dp"/>

    <TextView
        android:id="@+id/tv_age"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#666666"
        android:textSize="16sp"
        android:layout_marginTop="40dp"
        android:layout_marginLeft="10dp"/>
</RelativeLayout>

示例说明

下面给出两个完整的示例:

示例一:绑定一个简单的数据列表

在本示例中,我们会创建一个Android应用程序,用一个简单的数据列表绑定一个自定义的Adapter。数据列表中由学生的姓名和年龄组成。

步骤一:创建一个项目

使用Android Studio创建一个新项目,取名为“Student”,在这个项目中我们定义一个Student类,如下所示:

public class Student {
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

步骤二:创建一个自定义的Adapter

我们需要创建一个自定义的StudentAdapter,在这个Adapter中我们需要重写BaseAdapter中的方法因为它们是获取ListView中Item的必需方法。

public class StudentAdapter extends BaseAdapter {
    private List<Student> studentList;
    private LayoutInflater layoutInflater;

    public StudentAdapter(Context context, List<Student> studentList) {
        this.studentList = studentList;
        this.layoutInflater = LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
        return studentList.size();
    }

    @Override
    public Student getItem(int position) {
        return studentList.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;
        if (convertView == null) {
            convertView = layoutInflater.inflate(R.layout.item_student, parent, false);
            viewHolder = new ViewHolder();
            viewHolder.tvName = convertView.findViewById(R.id.tv_name);
            viewHolder.tvAge = convertView.findViewById(R.id.tv_age);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        Student student = getItem(position);
        viewHolder.tvName.setText(student.getName());
        viewHolder.tvAge.setText(String.valueOf(student.getAge()));
        return convertView;
    }

    private class ViewHolder {
        TextView tvName;
        TextView tvAge;
    }
}

步骤三:获取ListView控件并绑定数据

在MainActivity中,我们需要获取ListView控件,并绑定一些数据到ListView中,代码如下:

public class MainActivity extends AppCompatActivity {
    private ListView lvStudent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lvStudent = findViewById(R.id.lv_student);
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("李四", 20));
        StudentAdapter studentAdapter = new StudentAdapter(this, studentList);
        lvStudent.setAdapter(studentAdapter);
    }
}

在上面的示例中,首先要获取一个ListView控件,然后创建一个装有Student对象的List,接着实例化一个自定义Adapter并设置到ListView控件中。

步骤四:定义列表项布局

在res/layout文件夹中,创建一个名为item_student.xml的布局文件。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#666666"
        android:textSize="18sp"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="10dp"/>

    <TextView
        android:id="@+id/tv_age"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#666666"
        android:textSize="16sp"
        android:layout_marginTop="40dp"
        android:layout_marginLeft="10dp"/>
</RelativeLayout>

这里我们需要一个RelativeLayout,然后在里面添加两个TextView,用来展示学生的姓名和年龄。

示例二:自定义Item的布局

在本示例中,我们会创建一个Android应用程序,用自定义的Item展示一组学生的信息列表。每个Item的布局基于一个RelativeLayout组成的,内部包括一个ImageView和两个TextView,在这里我们将使用dataBinding。

步骤一:创建一个项目

使用Android Studio创建一个新项目,取名为“StudentInfo”,在这个项目中我们需要定义一个Student类,如下所示:

public class Student {
    private String name;
    private int age;
    private String avatar;

    public Student(String name, int age, String avatar) {
        this.name = name;
        this.age = age;
        this.avatar = avatar;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String getAvatar() {
        return avatar;
    }
}

步骤二:创建一个自定义的Adapter

我们可以创建一个StudentAdapter继承BaseAdapter,代码如下:

public class StudentAdapter extends BaseAdapter {
    private List<Student> studentList;
    private LayoutInflater layoutInflater;

    public StudentAdapter(Context context, List<Student> studentList) {
        this.studentList = studentList;
        this.layoutInflater = LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
        return studentList.size();
    }

    @Override
    public Student getItem(int position) {
        return studentList.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;
        if (convertView == null) {
            convertView = layoutInflater.inflate(R.layout.item_student, parent, false);
            viewHolder = new ViewHolder();
            viewHolder.ivAvatar = convertView.findViewById(R.id.iv_avatar);
            viewHolder.tvName = convertView.findViewById(R.id.tv_name);
            viewHolder.tvAge = convertView.findViewById(R.id.tv_age);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        Student student = getItem(position);
        Glide.with(viewHolder.ivAvatar.getContext()).load(student.getAvatar()).into(viewHolder.ivAvatar);
        viewHolder.tvName.setText(student.getName());
        viewHolder.tvAge.setText(String.valueOf(student.getAge()));
        return convertView;
    }

    private class ViewHolder {
        ImageView ivAvatar;
        TextView tvName;
        TextView tvAge;
    }
}

我们需要重写BaseAdapter中的方法,在viewHolder中可以获取子控件。

步骤三:创建一个布局文件

接下来,我们创建一个自定义的Item布局文件,其中包含一个ImageView和两个TextView,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
   <RelativeLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:padding="8dp">

       <ImageView
           android:id="@+id/iv_avatar"
           android:layout_width="48dp"
           android:layout_height="48dp"
           android:scaleType="centerCrop"/>

       <TextView
           android:id="@+id/tv_name"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_alignTop="@id/iv_avatar"
           android:layout_marginStart="12dp"
           android:layout_toEndOf="@id/iv_avatar"
           android:textColor="#333333"
           android:textSize="18sp"/>

       <TextView
           android:id="@+id/tv_age"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_below="@+id/tv_name"
           android:layout_marginStart="12dp"
           android:layout_toEndOf="@id/iv_avatar"
           android:textColor="#333333"
           android:textSize="16sp"/>
   </RelativeLayout>
</layout>

这个布局文件中包含一个ImageView和两个TextView,其中:

  • ImageView:用于展示学生的头像。
  • TextView(tv_name):用于展示学生的姓名。
  • TextView(tv_age):用于展示学生的年龄。

在这里我们使用了Android databinding自定义了一个layout来定义列表项的布局。

步骤四:设置Adapter

在MainActivity中,我们需要设置Adapter。代码如下:

public class MainActivity extends AppCompatActivity {
    private ListView lvStudent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lvStudent = findViewById(R.id.lv_student);
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("张三", 18, "https://picsum.photos/id/1/200/200"));
        studentList.add(new Student("李四", 20, "https://picsum.photos/id/2/200/200"));
        StudentAdapter studentAdapter = new StudentAdapter(this, studentList);
        lvStudent.setAdapter(studentAdapter);
    }
}

在上面的示例中,首先要获取一个ListView控件,然后创建一个装有Student对象的List,接着实例化一个自定义Adapter并设置到ListView控件中。

而且,在上面的代码中我们使用Glide库来进行头像的网络加载。

如此,我们就可以在界面中展示一个自定义的学生信息列表了。

最后,这些示例只是为了展现自定义Adapter的基本应用和主要流程,具体的实现方案和拓展需要参考具体的业务需求情况,才能制定最佳的设计方案。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android入门之实现自定义Adapter - Python技术站

(0)
上一篇 2023年6月25日
下一篇 2023年6月25日

相关文章

  • 字母a的ascii编码值和unicode编码值相同

    以下是字母a的ASCII编码值和Unicode编码值相同的完整攻略,包括两个示例说明。 1. ASCII编码和Unicode编码 ASCII编码是一种7位编码,用于表示128个字符,包括英文字母、数字和一些符号等。字母a的ASCII编码值为97。 Unicode编码是一种16位编码,用于表示65536个字符,包括世界上所有的语言和符号等。字母a的Unicod…

    other 2023年5月9日
    00
  • linux 截取时间段的日志

    Linux 截取时间段的日志 日志是 Linux 系统中重要的一部分,记录了系统运行过程中的各种信息。有时候,我们需要查找某个时间段内的特定日志信息,这时候就需要截取时间段的日志。本文将介绍多种通过 Linux 命令行方式截取时间段的日志的方法。 方法 1: grep + awk grep 是一种文本搜索工具,而 awk 则是一种文本分析工具。结合起来,可以…

    其他 2023年3月28日
    00
  • 基于部标jt/t809协议和javanetty框架构建gps位置监控平台

    基于部标JT/T809协议和Javanetty框架构建GPS位置监控平台的完整攻略,包括以下步骤: 步骤一:了解JT/T809协议 JT/T809协议是中国公安部发布的车辆卫星定位系统(GPS)数据交换协议,用于车辆监控和调度。该协议定义了车辆监控平台和车载终端之间的通信协议,包括数据格式、数据传输方式、数据加密等方面的规定。在构建GPS位置监控平台之前,需…

    other 2023年5月9日
    00
  • angular项目中使用antd日历组件

    以下是关于“Angular项目中使用Antd日历组件”的完整攻略,过程中包含两个示例。 背景 Antd是一个基于React的UI组件库但是它也提供了一些Angular组件。其中,Antd的日历组件非常实用,可以帮助我们快速构建日历。本攻略将介绍如何在Angular项目中使用Antd日历组件。 基本原理 在Angular项目中使用Antd日历组,我们需要先安装…

    other 2023年5月9日
    00
  • 修改Oracle 数据库实例字符集

    下面是关于修改Oracle数据库实例字符集的完整攻略,包括修改字符集的原因、修改步骤和两个示例说明。 修改字符集的原因 在Oracle数据库中,字符集是用于存储和处理数据的编码方式。如果数据库实例的字符集与应用程序或客户端的字符集不一致,就会导致数据存储和处理的问题,如乱码、字符集转换错误等。因此,有时需要修改Oracle数据库实例的字符集,以满足应用程序或…

    other 2023年5月6日
    00
  • mysql数据表按照某个字段分类输出

    需要实现按照某个字段分类输出,我们可以使用MySQL中的GROUP BY语句来完成。 GROUP BY语句根据指定的列对数据进行分组,并返回每组的聚合值,如计数、平均值等。 以下是使用GROUP BY语句实现按照某个字段分类输出的完整攻略: 创建示例表格 为方便进行说明,首先我们创建一个示例表格。该表格将记录每个用户的姓名、性别、年龄和所在城市。 我们可以通…

    other 2023年6月25日
    00
  • 解析Linux下C++编译和链接

    我们来详细讲解一下如何在Linux下进行C++编译和链接。 首先我们需要编写一个C++源文件,例如下面这个示例: #include <iostream> using namespace std; int main() { cout << "Hello World!" << endl; return 0;…

    other 2023年6月26日
    00
  • navicat查询功能

    Navicat查询功能 Navicat 是一款强大的数据库管理工具,它支持多种数据库,包括 MySQL、PostgreSQL、Oracle、SQLite 等,而查询功能是 Navicat 最常用的功能之一。 在 Navicat 中,查询是通过 SQL 语句来实现的。用户可以使用 Navicat 提供的图形化界面来构造 SQL 语句,也可以直接编写 SQL 语…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部