当前位置:   article > 正文

学习Android的第十五天_android 适配器

android 适配器

目录

Android Adapter 适配器

MVC 模式

Adapter

ArrayAdapter 泛型

ArrayAdapter 构造函数的第二个参数

范例

SimpleAdapter 适配器

范例

SimpleCursorAdapter 适配器

范例

参考文档


Android Adapter 适配器

Android 中的 Adapter(适配器)是用于在 UI 组件(如 ListView、RecyclerView)和数据之间建立连接的桥梁。它负责将数据源中的数据转换成视图(View),然后将这些视图展示在 UI 组件上供用户查看和操作。

如微信页面中,Adapter 负责将微信中的消息数据转换成合适的视图,并将这些视图显示在列表中。这样用户就可以通过滚动列表查看消息,点击消息进行相应操作等。

Adapter 的主要作用包括:

  1. 将数据源转换成视图:Adapter 从数据源中获取数据,并将其转换成可显示在 UI 组件上的视图。

  2. 管理视图复用:在列表等大量数据的情况下,Adapter 负责管理视图的复用,以减少内存开销和提高性能。

  3. 处理用户交互:Adapter 可以处理用户与列表中项的交互,例如点击、长按等操作。

  4. 提供数据更新机制:Adapter 提供了机制来通知 UI 组件数据的变化,以便及时更新视图。

MVC 模式

为了更好的理解 Adapter 的作用,我们先来了解下 MVC 模式(详细可见此章

MVC(Model-View-Controller)模式是一种软件架构模式,用于将应用程序分成三个核心组件:模型(Model)、视图(View)和控制器(Controller)。每个组件都有不同的职责,彼此之间相互独立,这样可以使代码更易于管理、维护和扩展。

模型(Model)

  • 模型代表应用程序的数据和业务逻辑。
  • 模型负责存储、检索和更新数据,以及执行与数据相关的操作。
  • 模型通常是独立于用户界面的,可以被多个视图共享。
  • 在 Android 中,模型通常表示数据源、数据库、网络请求等。

视图(View)

  • 视图是用户界面的可视化部分,负责向用户展示数据和接收用户输入。
  • 视图通常是模型的直接表示,但不包含任何业务逻辑。
  • 视图是 passives,即 passives 响应控制器或模型的更改,并相应地更新自身。
  • 在 Android 中,视图可以是 Activity、Fragment、XML 布局文件等。

控制器(Controller)

  • 控制器是模型和视图之间的中介,负责协调用户输入、数据更新和视图更新之间的交互。
  • 控制器捕获用户的操作,并根据这些操作更新模型或视图。
  • 控制器可以包含一些业务逻辑,但主要是用来管理应用程序的流程和交互。
  • 在 Android 中,控制器可以是 Activity、Fragment、自定义控制器等。

而Adapter 在某种程度上实现了 MVC 模式中控制器(Controller)的功能,因为它在数据模型和用户界面之间起到了连接的作用。但严格来说,Adapter 更多地用于实现数据与视图之间的适配,而不是控制整个应用程序的逻辑和流程。

Adapter

在 Android 中,Adapter 是一个重要的概念,用于将数据与 UI 组件(如 ListView、RecyclerView)进行连接和适配。

Adapter 的继承关系图

下面是一些常见的 Adapter 类及其继承关系:

BaseAdapter:

  • 抽象类,是 Android 中使用最广泛的 Adapter 之一。
  • 提供了一些基本的实现,但需要开发者自己实现 getCount()、getItem()、getItemId() 和 getView() 等方法。
  • 适用于自定义的数据类型和视图布局。

ArrayAdapter:

  • 继承自 BaseAdapter。
  • 支持泛型操作,可以方便地与数组或列表进行适配。
  • 通常用于展示简单的列表数据,例如只包含一行文字。

SimpleAdapter:

  • 继承自 BaseAdapter。
  • 提供了一种简单而灵活的方式来将数据与视图绑定。
  • 可以自定义多种效果,例如列表项中包含不同的控件(TextView、ImageView 等)。

SimpleCursorAdapter:

  • 继承自 CursorAdapter,间接地实现了 BaseAdapter 接口。
  • 用于将数据库中的查询结果(Cursor)与视图绑定,通常用于显示数据库查询结果。
  • 不推荐使用,因为它不够灵活,只适用于显示简单文本类型的 ListView。

ArrayAdapter 泛型

ArrayAdapter 支持泛型数据,这使得它可以与各种类型的数据集合进行适配,并在 ListView 或 Spinner 等控件中显示。

使用泛型的好处是可以在编译时就进行类型检查,从而提高代码的安全性和可读性。通过将 ArrayAdapter 声明为泛型类,可以指定它要适配的数据类型,以便在使用时编译器可以执行类型检查。

例如,如果有一个包含整数的列表,可以这样使用泛型 ArrayAdapter:

  1. ArrayList<Integer> dataList = new ArrayList<>();
  2. dataList.add(1);
  3. dataList.add(2);
  4. dataList.add(3);
  5. ArrayAdapter<Integer> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, dataList);

这样,当您尝试将不兼容的数据类型添加到 ArrayAdapter 中时,编译器会发出警告或错误,从而帮助您在编译时捕获潜在的类型错误。

使用泛型 ArrayAdapter 可以更加安全和便捷地处理不同类型的数据集合,并在 UI 控件中进行显示。

ArrayAdapter 构造函数的第二个参数

android.R.layout.simple_expandable_list_item_1 是 ArrayAdapter 构造函数的第二个参数,用于指定要为 ListView 中的每个列表项使用的布局模板。

这些布局模板是 Android 系统提供的预定义布局,可以根据需要选择适合的模板来展示列表项。

下面是几种常见的布局模板:

  • android.R.layout.simple_list_item_1:单独一行的文本框,适合用于显示简单的文本信息。
  • android.R.layout.simple_list_item_2:由两个文本框组成的列表项,适合用于显示比较复杂的文本信息,例如标题和副标题。
  • android.R.layout.simple_list_item_checked:每个列表项都包含一个已选中的列表项,通常与 ListView 的选择模式相关联,可用于实现多选列表。
  • android.R.layout.simple_list_item_multiple_choice:每个列表项都带有一个复选框,适合用于实现多选列表。
  • android.R.layout.simple_list_item_single_choice:每个列表项都带有一个单选钮,适合用于实现单选列表。

范例

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical"
  6. android:gravity="center">
  7. <ListView
  8. android:id="@+id/listView"
  9. android:layout_width="match_parent"
  10. android:layout_height="match_parent" />
  11. </LinearLayout>
  1. package com.example.myapplication;
  2. import android.os.Bundle;
  3. import android.widget.ArrayAdapter;
  4. import android.widget.ListView;
  5. import androidx.appcompat.app.AppCompatActivity;
  6. import java.util.ArrayList;
  7. public class MainActivity extends AppCompatActivity {
  8. @Override
  9. protected void onCreate(Bundle savedInstanceState) {
  10. super.onCreate(savedInstanceState);
  11. setContentView(R.layout.activity_main);
  12. // 准备数据源
  13. ArrayList<String> dataList = new ArrayList<>();
  14. dataList.add("项目 1:Java");
  15. dataList.add("项目 2:C#");
  16. dataList.add("项目 3:Python");
  17. dataList.add("项目 4:C++");
  18. dataList.add("项目 5:PHP");
  19. // 实例化 ArrayAdapter
  20. ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, dataList);
  21. // 设置适配器
  22. ListView listView = findViewById(R.id.listView);
  23. listView.setAdapter(adapter);
  24. }
  25. }

SimpleAdapter 适配器

SimpleAdapter 是 Android 中最简单的适配器之一,尽管它简单,但它提供了强大的功能,适用于许多常见的数据展示需求。SimpleAdapter 可以用于将数据源中的数据与 UI 组件(如 ListView)进行绑定,并在列表中显示。

SimpleAdapter 的主要特点和功能包括:

  • 简单易用:SimpleAdapter 的使用非常简单,只需提供数据源和布局资源即可快速实现数据与视图的绑定。
  • 支持多种数据类型:SimpleAdapter 可以适配各种数据类型,包括字符串、整数、图片等。
  • 灵活的布局控制:SimpleAdapter 允许您通过定义布局资源来控制每个列表项的显示内容和样式。
  • 支持多种视图类型:SimpleAdapter 支持在列表中显示多种类型的视图,例如 TextView、ImageView 等。
  • 数据更新方便:SimpleAdapter 提供了便捷的方法来更新数据源,使得数据的动态更新变得简单。

虽然 SimpleAdapter 功能简单,但在许多场景下都可以满足基本的需求,特别是对于那些不需要复杂定制的列表展示,SimpleAdapter 是一个非常方便的选择。

范例

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical"
  6. android:gravity="center">
  7. <ListView
  8. android:id="@+id/listView"
  9. android:layout_width="match_parent"
  10. android:layout_height="match_parent" />
  11. </LinearLayout>
  1. package com.example.myapplication;
  2. import android.os.Bundle;
  3. import android.widget.ListView;
  4. import android.widget.SimpleAdapter;
  5. import androidx.appcompat.app.AppCompatActivity;
  6. import java.util.ArrayList;
  7. import java.util.HashMap;
  8. import java.util.List;
  9. import java.util.Map;
  10. public class MainActivity extends AppCompatActivity {
  11. @Override
  12. protected void onCreate(Bundle savedInstanceState) {
  13. super.onCreate(savedInstanceState);
  14. setContentView(R.layout.activity_main);
  15. // 准备数据源
  16. List<Map<String, String>> dataList = new ArrayList<>();
  17. Map<String, String> item1 = new HashMap<>();
  18. item1.put("title", "项目1");
  19. item1.put("subtitle", "项目1的副标题");
  20. dataList.add(item1);
  21. Map<String, String> item2 = new HashMap<>();
  22. item2.put("title", "项目2");
  23. item2.put("subtitle", "项目2的副标题");
  24. dataList.add(item2);
  25. // 定义布局资源
  26. int layoutResource = android.R.layout.simple_list_item_2;
  27. // 定义数据源中的键名
  28. String[] from = {"title", "subtitle"};
  29. // 定义布局资源中的控件 id
  30. int[] to = {android.R.id.text1, android.R.id.text2};
  31. // 实例化 SimpleAdapter
  32. SimpleAdapter adapter = new SimpleAdapter(this, dataList, layoutResource, from, to);
  33. // 设置适配器
  34. ListView listView = findViewById(R.id.listView);
  35. listView.setAdapter(adapter);
  36. }
  37. }

效果图:

SimpleCursorAdapter 适配器

SimpleCursorAdapter 是用于将数据库查询结果(Cursor)与视图控件(如 ListView)进行绑定的适配器。它主要用于从 SQLite 数据库中读取数据并将其显示在 UI 控件中。

范例

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical"
  6. android:gravity="center">
  7. <ListView
  8. android:id="@+id/listView"
  9. android:layout_width="match_parent"
  10. android:layout_height="match_parent" />
  11. </LinearLayout>
  1. package com.example.myapplication;
  2. import android.Manifest;
  3. import android.content.pm.PackageManager;
  4. import android.database.Cursor;
  5. import android.os.Bundle;
  6. import android.provider.ContactsContract;
  7. import android.widget.ListView;
  8. import android.widget.SimpleCursorAdapter;
  9. import android.widget.Toast;
  10. import androidx.appcompat.app.AppCompatActivity;
  11. import androidx.core.app.ActivityCompat;
  12. import androidx.core.content.ContextCompat;
  13. public class MainActivity extends AppCompatActivity {
  14. private static final int PERMISSIONS_REQUEST_READ_CONTACTS = 100;
  15. private ListView listView;
  16. private SimpleCursorAdapter adapter;
  17. @Override
  18. protected void onCreate(Bundle savedInstanceState) {
  19. super.onCreate(savedInstanceState);
  20. setContentView(R.layout.activity_main);
  21. listView = findViewById(R.id.listView);
  22. // 检查是否有读取联系人权限,如果没有则请求权限
  23. if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)
  24. != PackageManager.PERMISSION_GRANTED) {
  25. ActivityCompat.requestPermissions(this,
  26. new String[]{Manifest.permission.READ_CONTACTS},
  27. PERMISSIONS_REQUEST_READ_CONTACTS);
  28. } else {
  29. // 如果已经有权限,直接加载联系人数据
  30. loadContacts();
  31. }
  32. }
  33. private void loadContacts() {
  34. // 定义要查询的字段
  35. String[] projection = {ContactsContract.Contacts._ID,
  36. ContactsContract.Contacts.DISPLAY_NAME,
  37. ContactsContract.CommonDataKinds.Phone.NUMBER};
  38. // 查询联系人
  39. Cursor cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
  40. projection, null, null, null);
  41. // 定义要显示的字段
  42. String[] fromColumns = {ContactsContract.Contacts.DISPLAY_NAME,
  43. ContactsContract.CommonDataKinds.Phone.NUMBER};
  44. int[] toViews = {android.R.id.text1, android.R.id.text2};
  45. // 实例化 SimpleCursorAdapter,并将数据绑定到 ListView
  46. adapter = new SimpleCursorAdapter(this,
  47. android.R.layout.simple_list_item_2, cursor,
  48. fromColumns, toViews, 0);
  49. listView.setAdapter(adapter);
  50. }
  51. @Override
  52. public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
  53. super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  54. if (requestCode == PERMISSIONS_REQUEST_READ_CONTACTS) {
  55. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
  56. // 用户同意了权限请求,加载联系人数据
  57. loadContacts();
  58. } else {
  59. // 用户拒绝了权限请求,显示提示信息
  60. Toast.makeText(this, "无法读取联系人,因为未授予权限", Toast.LENGTH_SHORT).show();
  61. }
  62. }
  63. }
  64. }

最后在 AndroidManifest.xml 文件中,添加了读取联系人权限的声明: 

  1. </application>
  2. <uses-permission android:name="android.permission.READ_CONTACTS"/>
  3. </manifest>

打开模拟机的时候要在读取联系人权限的时候点击 OK

参考文档

官方文档: Adapter

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/866055
推荐阅读
相关标签
  

闽ICP备14008679号