目录
Android Adapter 适配器
MVC 模式
Adapter
ArrayAdapter 泛型
ArrayAdapter 构造函数的第二个参数
范例
SimpleAdapter 适配器
范例
SimpleCursorAdapter 适配器
范例
参考文档
Android 中的 Adapter(适配器)是用于在 UI 组件(如 ListView、RecyclerView)和数据之间建立连接的桥梁。它负责将数据源中的数据转换成视图(View),然后将这些视图展示在 UI 组件上供用户查看和操作。
如微信页面中,Adapter 负责将微信中的消息数据转换成合适的视图,并将这些视图显示在列表中。这样用户就可以通过滚动列表查看消息,点击消息进行相应操作等。
Adapter 的主要作用包括:
将数据源转换成视图:Adapter 从数据源中获取数据,并将其转换成可显示在 UI 组件上的视图。
管理视图复用:在列表等大量数据的情况下,Adapter 负责管理视图的复用,以减少内存开销和提高性能。
处理用户交互:Adapter 可以处理用户与列表中项的交互,例如点击、长按等操作。
提供数据更新机制:Adapter 提供了机制来通知 UI 组件数据的变化,以便及时更新视图。
为了更好的理解 Adapter 的作用,我们先来了解下 MVC 模式(详细可见此章)
MVC(Model-View-Controller)模式是一种软件架构模式,用于将应用程序分成三个核心组件:模型(Model)、视图(View)和控制器(Controller)。每个组件都有不同的职责,彼此之间相互独立,这样可以使代码更易于管理、维护和扩展。
模型(Model):
视图(View):
控制器(Controller):
而Adapter 在某种程度上实现了 MVC 模式中控制器(Controller)的功能,因为它在数据模型和用户界面之间起到了连接的作用。但严格来说,Adapter 更多地用于实现数据与视图之间的适配,而不是控制整个应用程序的逻辑和流程。
在 Android 中,Adapter 是一个重要的概念,用于将数据与 UI 组件(如 ListView、RecyclerView)进行连接和适配。
Adapter 的继承关系图
下面是一些常见的 Adapter 类及其继承关系:
BaseAdapter:
ArrayAdapter:
SimpleAdapter:
SimpleCursorAdapter:
ArrayAdapter 支持泛型数据,这使得它可以与各种类型的数据集合进行适配,并在 ListView 或 Spinner 等控件中显示。
使用泛型的好处是可以在编译时就进行类型检查,从而提高代码的安全性和可读性。通过将 ArrayAdapter 声明为泛型类,可以指定它要适配的数据类型,以便在使用时编译器可以执行类型检查。
例如,如果有一个包含整数的列表,可以这样使用泛型 ArrayAdapter:
ArrayList dataList = new ArrayList<>();
dataList.add(1);
dataList.add(2);
dataList.add(3);
ArrayAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, dataList);
这样,当您尝试将不兼容的数据类型添加到 ArrayAdapter 中时,编译器会发出警告或错误,从而帮助您在编译时捕获潜在的类型错误。
使用泛型 ArrayAdapter 可以更加安全和便捷地处理不同类型的数据集合,并在 UI 控件中进行显示。
android.R.layout.simple_expandable_list_item_1 是 ArrayAdapter 构造函数的第二个参数,用于指定要为 ListView 中的每个列表项使用的布局模板。
这些布局模板是 Android 系统提供的预定义布局,可以根据需要选择适合的模板来展示列表项。
下面是几种常见的布局模板:
package com.example.myapplication;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 准备数据源
ArrayList dataList = new ArrayList<>();
dataList.add("项目 1:Java");
dataList.add("项目 2:C#");
dataList.add("项目 3:Python");
dataList.add("项目 4:C++");
dataList.add("项目 5:PHP");
// 实例化 ArrayAdapter
ArrayAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, dataList);
// 设置适配器
ListView listView = findViewById(R.id.listView);
listView.setAdapter(adapter);
}
}
SimpleAdapter 是 Android 中最简单的适配器之一,尽管它简单,但它提供了强大的功能,适用于许多常见的数据展示需求。SimpleAdapter 可以用于将数据源中的数据与 UI 组件(如 ListView)进行绑定,并在列表中显示。
SimpleAdapter 的主要特点和功能包括:
虽然 SimpleAdapter 功能简单,但在许多场景下都可以满足基本的需求,特别是对于那些不需要复杂定制的列表展示,SimpleAdapter 是一个非常方便的选择。
package com.example.myapplication;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 准备数据源
List
效果图:
SimpleCursorAdapter 是用于将数据库查询结果(Cursor)与视图控件(如 ListView)进行绑定的适配器。它主要用于从 SQLite 数据库中读取数据并将其显示在 UI 控件中。
package com.example.myapplication;
import android.Manifest;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
public class MainActivity extends AppCompatActivity {
private static final int PERMISSIONS_REQUEST_READ_CONTACTS = 100;
private ListView listView;
private SimpleCursorAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = findViewById(R.id.listView);
// 检查是否有读取联系人权限,如果没有则请求权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_CONTACTS},
PERMISSIONS_REQUEST_READ_CONTACTS);
} else {
// 如果已经有权限,直接加载联系人数据
loadContacts();
}
}
private void loadContacts() {
// 定义要查询的字段
String[] projection = {ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER};
// 查询联系人
Cursor cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
projection, null, null, null);
// 定义要显示的字段
String[] fromColumns = {ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER};
int[] toViews = {android.R.id.text1, android.R.id.text2};
// 实例化 SimpleCursorAdapter,并将数据绑定到 ListView
adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_2, cursor,
fromColumns, toViews, 0);
listView.setAdapter(adapter);
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSIONS_REQUEST_READ_CONTACTS) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 用户同意了权限请求,加载联系人数据
loadContacts();
} else {
// 用户拒绝了权限请求,显示提示信息
Toast.makeText(this, "无法读取联系人,因为未授予权限", Toast.LENGTH_SHORT).show();
}
}
}
}
最后在 AndroidManifest.xml 文件中,添加了读取联系人权限的声明:
打开模拟机的时候要在读取联系人权限的时候点击 OK
官方文档: Adapter