当我们在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技术站