Android入门之实现自定义Adapter

yizhihongxing

当我们在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日

相关文章

  • 深入理解docker容器中的uid和gid

    深入理解Docker容器中的UID和GID Docker是一个流行的容器化平台,它允许用户打包应用程序和依赖项,并将它们独立地运行在一个虚拟化的环境中。Docker容器通常运行在Linux操作系统中,而容器内部的文件和进程是由Docker守护进程运行的。 在容器中运行应用程序时,需要访问主机文件系统或其他资源。由于容器本身是隔离的,所以涉及到容器内部和外部资…

    other 2023年6月26日
    00
  • Android开发5:应用程序窗口小部件App Widgets的实现(附demo)

    首先,让我们概括一下“Android开发5:应用程序窗口小部件App Widgets的实现”的实现步骤: 了解App Widget的基本概念和工作原理; 创建App Widget Provider,并在AndroidManifest.xml中声明; 创建App Widget的布局文件; 创建App Widget更新的RemoteViews对象; 更新App …

    other 2023年6月25日
    00
  • oracleif-else条件判断结构

    当然,我很乐意为您提供有关“Oracle if-else条件判断结构”的完整攻略。以下是详细的步骤和两个示例: 1. 什么是if-else条件判断结构? if-else条件判断结构是一种编程结构,用于根据条件执行不同的代码块。在Oracle中,可以使用if-else语句来实现条件判断。 以下是if-else语句的基本语法: IF condition THEN…

    other 2023年5月6日
    00
  • Github如何在Linux系统下创建本地仓库

    Github如何在Linux系统下创建本地仓库的完整攻略 本文将为您详细讲解如何在Linux系统下创建本地仓库并将其上传到Github,包括环境搭建、仓库创建、本地仓库初始化、本地仓库提交和上传到Github等步骤。 环境搭建 在开始创建本地仓库之前,需要先在Linux系统中安装Git。可以使用以下命令进行安装: sudo apt-get update su…

    other 2023年5月6日
    00
  • tk.mybatis如何扩展自己的通用mapper

    tk.mybatis是一个基于MyBatis的轻量级通用Mapper框架,可以帮助开发者快速开发通用的数据库操作,省去大部分重复编写CRUD方法的工作。如果需要扩展自己的通用Mapper,我们需要遵循以下步骤: 自定义接口及Mapper文件 我们可以通过继承通用Mapper提供的BaseMapper接口,再定义自己的Mapper接口,例如UserMapper…

    other 2023年6月26日
    00
  • Android控件系列之CheckBox使用介绍

    Android控件系列之CheckBox使用介绍 什么是CheckBox控件? CheckBox控件是一个可以被选中或取消选中的复选框控件,常用于表示某些选项的状态。CheckBox通常与TextView或者Button等控件一起使用,用于辅助用户进行操作。 CheckBox控件的使用步骤 步骤1:在xml布局中添加CheckBox控件 在xml布局文件中使…

    other 2023年6月27日
    00
  • ThinkPHP中类的构造函数_construct()与_initialize()的区别详解

    题目要求详细讲解 “ThinkPHP中类的构造函数_construct()与_initialize()的区别详解”,下面针对这个话题,我将从以下几个方面进行详细的讲解: 什么是构造函数和初始化函数 二者的区别 示例说明 构造函数和初始化函数 在介绍二者的区别之前,我们需要了解一下什么是构造函数和初始化函数。 构造函数 构造函数(Constructor Fun…

    other 2023年6月26日
    00
  • PHP错误WARNING: SESSION_START() [FUNCTION.SESSION-START]解决方法

    PHP错误WARNING: SESSION_START() [FUNCTION.SESSION-START]的解决方法如下: 1. 确认PHP版本和错误信息 首先要确认PHP版本是否符合要求,可以检查PHP配置文件(php.ini)中的session配置项是否开启,也可以查看PHP的错误日志,确认错误信息是不是和session相关的。 2. 检查PHP代码 …

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部