Android开发 - (适配器)Adapter类中ArrayAdapter实现类详细解析

简介

  • 常用于将数组或列表的数据绑定到 ListView、Spinner 等组件上

具体作用

  • 数组数据映射到 UI 组件(如 ListView、Spinner 等)上的角色。它是 BaseAdapter 的一个子类,专门用于处理简单的数据集合,如数组列表ArrayAdapter 简化了数据到视图映射的过程,使得开发者能够以更少的代码实现数据的展示。它的主要作用为以下几点:
    • 数据绑定:它能够将一组数据(如字符串数组、整数数组或任何对象的数组)绑定到列表视图(ListView)下拉列表(Spinner)等组件上。这意味着你可以通过更改适配器中的数据来更新 UI 组件的显示内容
    • 视图管理ArrayAdapter 负责为每个数据项创建重用视图(View)。当列表项需要显示时,适配器会从已经存在的视图池中查找可重用的视图,如果找不到,则使用提供的布局资源来创建新的视图。这样做可以提高列表的滚动性能,因为创建和销毁视图是昂贵的操作
    • 数据更新:当数据集合发生变化时(例如,添加、删除或修改数据项),你可以通知适配器(通过调用 notifyDataSetChanged() 方法),然后适配器会更新与之关联的 UI 组件,以反映这些更改。
    • 类型安全:虽然 ArrayAdapter 可以处理任何类型的对象数组,但最好使用泛型版本的 ArrayAdapter<T> 来确保类型安全。这有助于避免在编译时期出现类型相关的错误
    • 自定义视图:你可以通过提供自定义的布局资源来定义每个列表项的外观。这个布局资源应该包含一个或多个视图(如 TextView、ImageView 等),并且你需要指定哪个视图应该用于显示数据。
    • 简单性和易用性:对于简单的数据列表,ArrayAdapter 提供了一种快速且简单的方法来将它们显示在 UI 上,而无需编写大量的适配器代码。这使得开发者能够更专注于应用程序的其他方面

参数、方法解析

  • ArrayAdapter(Context context, int resource, T[] objects):基本构造方法;这个构造方法适用于当你有一个数组,并且想要将其内容展示在列表视图中时使用

    String[] items = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5"};
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, mList);
    
    • 参数解析
      • context上下文对象,通常为ActivityFragment的上下文
      • resource:表示每个数据项的布局资源文件ID,例如android.R.layout.simple_list_item_1
      • objects:一个数组,包含要适配到视图中的数据
  • ArrayAdapter(Context context, int resource, List<T> objects)List构造方法;这个构造方法允许你使用一个 List 集合来初始化适配器,这在数据可能发生变化时非常有用,因为你可以直接修改 List 集合来更新视图

    List<Fragment> mList = new ArrayList<Fragment>();
    mList.add("Item 1");
    mList.add("Item 2");
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, mList);
    
    • 参数解析
      • context上下文对象,通常为ActivityFragment的上下文
      • resource:表示每个数据项的布局资源文件ID,例如android.R.layout.simple_list_item_1
      • objects:一个 List 集合,包含要适配到视图中的数据
  • ArrayAdapter(Context context, int resource, int textViewResourceId, T[] objects):带有布局TextView ID 的基本构造方法;这个构造方法提供了更高的灵活性,允许你使用数组初始化适配器后指定数据应该被填充到布局中的哪个具体的 TextView 控件

    String[] items = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5"};
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, R.id.textView_1, mList);
    
    • 参数解析
      • context上下文对象,通常为ActivityFragment的上下文
      • resource:表示每个数据项的布局资源文件ID,例如android.R.layout.simple_list_item_1
      • textViewResourceId:在 resource 指定的布局文件中,用于显示数据的 TextViewID。这个参数允许你指定数据应该被填充到布局中的哪个 TextView 控件中;例如R.id.textView_1
      • objects:一个数组,包含要适配到视图中的数据。
  • ArrayAdapter(Context context, int resource, int textViewResourceId, List<T> objects):带有布局TextView IDList构造方法;这个构造方法提供了更高的灵活性,允许你使用List 集合初始化适配器后指定数据应该被填充到布局中的哪个具体的 TextView 控件

    List<Fragment> mList = new ArrayList<Fragment>();
    mList.add("Item 1");
    mList.add("Item 2");
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, R.id.textView_1, mList);
    
    • 参数解析
      • context上下文对象,通常为ActivityFragment的上下文
      • resource:表示每个数据项的布局资源文件ID,例如android.R.layout.simple_list_item_1
      • textViewResourceId:在 resource 指定的布局文件中,用于显示数据的 TextViewID。这个参数允许你指定数据应该被填充到布局中的哪个 TextView 控件中;例如R.id.textView_1
      • objects:一个 List 集合,包含要适配到视图中的数据
  • adapter.add(T object);

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1);
    adapter.add("Item 1");
    
    • 参数解析
      • object:向适配器中添加一个数据项
  • adapter.addAll(Collection<? extends T> collection);

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1);
    List<String> dataList = new ArrayList<String>();
    dataList.add("Item 1");
    dataList.add("Item 2");
    adapter.addAll(dataList);
    
    • 参数解析
      • collection:向适配器中添加一个集合的数据项
  • adapter.clear();:清空适配器中的所有数据项

  • adapter.getCount();:获取适配器中数据项的数量

  • adapter.getItem(int position);:根据位置获取Cursor中对应的数据项。然而,在CursorAdapter的实现中,这个方法通常只是简单地返回Cursor对象本身,并将其位置移动到指定的位置。实际上,并不建议直接使用返回的Cursor对象,因为这会破坏Cursor的位置状态

    // 假设你有一个ArrayAdapter<String>,它管理着一个字符串数组  
    String[] mList = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5"};
    ArrayAdapter<String> adapter = new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, mList);
    int position = 0; // 假设你想获取第一个项 
    String item = adapter.getItem(position);	//这里假设yourStringList是String类型的列表,此时,item就是位于position位置的字符串项
    
    • 参数解析
      • position:获取指定位置的数据项
  • adapter.getView(int position, View convertView, ViewGroup parent)获取数据项的视图,用于在ListViewSpinner中显示数据。这个方法通常不需要直接调用而是由系统在需要显示列表项时自动调用

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1);
    ListView listView = view.findViewById(android.R.id.listView_1);
    View view = adapter.getView(position, null, listView);
    
    • 参数解析

      • position:要获取视图的数据项的位置(索引)

      • convertView:可复用的视图对象,用于优化列表性能,如果为null,表示要获取一个新的视图对象;如果不为null,则可以重复使用该视图对象,避免重复创建

      • parent:父视图,即该视图将被添加到的父容器(例如ListView)

  • adapter.notifyDataSetChanged();:当数据发生变化时,可以通过适配器的方法进行更新,然后通知列表重新显示更新后的数据

    adapter.add("New Item");
    adapter.notifyDataSetChanged();
    

使用场景解析

  • ArrayAdapterAndroid 提供的一种适配器,用于将数据源(通常是一个数组或列表)绑定到 ListViewGridView其他视图组件中。它通常用于简单的数据显示场景,并且适用于数据集较小或者变化较少的情况。以下是一些常见的 ArrayAdapter 使用场景

    简单文本列表

    • 场景描述:展示一组简单的字符串,例如显示一系列城市名称任务列表新闻标题

    • 示例:假设你有一个城市名称的数组,想将这些城市名称显示在一个 ListView

      // 数据源
      String[] cities = {"New York", "Los Angeles", "Chicago", "Houston", "Phoenix"};
      
      // 创建 ArrayAdapter
      ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, cities);
      
      // 将 ArrayAdapter 设置为 ListView 的适配器
      ListView listView = findViewById(R.id.listView);
      listView.setAdapter(adapter);
      

    显示联系人列表

    • 场景描述:在一个联系人应用中,展示联系人名称的列表,数据来源可能是一个字符串数组

    • 示例:假设你有一组联系人名称,使用 ArrayAdapter 显示这些名称

      // 联系人名称数据源
      String[] contacts = {"Alice", "Bob", "Charlie", "David", "Eve"};
      
      // 创建 ArrayAdapter
      ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, contacts);
      
      // 将 ArrayAdapter 设置为 ListView 的适配器
      ListView listView = findViewById(R.id.listView);
      listView.setAdapter(adapter);
      

    显示单选项或复选项列表

    • 场景描述:在设置选项页面中展示一组可选项,例如单选按钮复选框的选项列表

    • 示例:假设你有一个设置选项列表,需要展示在 ListView

      // 选项数据源
      String[] settingsOptions = {"Wi-Fi", "Bluetooth", "Data Usage", "Notifications", "Display"};
      
      // 创建 ArrayAdapter
      ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_checked, settingsOptions);
      
      // 将 ArrayAdapter 设置为 ListView 的适配器
      ListView listView = findViewById(R.id.listView);
      listView.setAdapter(adapter);
      

    显示自定义对象列表

    • 场景描述:你可以使用自定义布局来显示包含多个字段的自定义对象,例如用户信息产品列表

    • 示例:假设你有一个自定义的 User 类,包含用户名邮箱。你可以创建自定义布局来显示这些信息

      • 自定义布局文件res/layout/user_item.xml

        <?xml version="1.0" encoding="utf-8"?>
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:padding="16dp">
        
            <TextView
                android:id="@+id/username"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="18sp"
                android:textStyle="bold"/>
        
            <TextView
                android:id="@+id/email"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="14sp"/>
        </LinearLayout>
        
      • 自定义ArrayAdapter类: UserAdapter.java

        package com.example.arrayadapterexample;
        
        import android.content.Context;
        import android.view.LayoutInflater;
        import android.view.View;
        import android.view.ViewGroup;
        import android.widget.ArrayAdapter;
        import android.widget.TextView;
        
        import java.util.List;
        
        /**
         * 自定义 ArrayAdapter,用于将 User 对象绑定到 ListView。
         */
        public class UserAdapter extends ArrayAdapter<User> {
        
            public UserAdapter(Context context, List<User> users) {
                super(context, 0, users);
            }
        
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                // 获取当前用户对象
                User user = getItem(position);
        
                // 如果视图为空,创建新视图
                if (convertView == null) {
                    convertView = LayoutInflater.from(getContext()).inflate(R.layout.user_item, parent, false);
                }
        
                // 获取视图中的 TextView
                TextView usernameTextView = convertView.findViewById(R.id.username);
                TextView emailTextView = convertView.findViewById(R.id.email);
        
                // 设置 TextView 的内容
                usernameTextView.setText(user.getUsername());
                emailTextView.setText(user.getEmail());
        
                return convertView;
            }
        }
        
      • 创建 User 类

        public class User {
            private String username;
            private String email;
        
            public User(String username, String email) {
                this.username = username;
                this.email = email;
            }
        
            public String getUsername() {
                return username;
            }
        
            public String getEmail() {
                return email;
            }
        }
        
      • 启动类

        package com.example.arrayadapterexample;
        
        import android.os.Bundle;
        import android.widget.ListView;
        
        import androidx.appcompat.app.AppCompatActivity;
        
        import java.util.ArrayList;
        import java.util.List;
        
        /**
         * 主活动,设置 ListView 并使用自定义 ArrayAdapter 绑定 User 数据。
         */
        public class MainActivity extends AppCompatActivity {
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
        
                // 创建 User 数据源
                List<User> users = new ArrayList<>();
                users.add(new User("Alice", "alice@example.com"));
                users.add(new User("Bob", "bob@example.com"));
                users.add(new User("Charlie", "charlie@example.com"));
        
                // 创建 UserAdapter
                UserAdapter adapter = new UserAdapter(this, users);
        
                // 将 UserAdapter 设置为 ListView 的适配器
                ListView listView = findViewById(R.id.listView);
                listView.setAdapter(adapter);
            }
        }
        

    动态更新数据

    • 场景描述ArrayAdapter 适合处理动态数据更新,例如在列表中添加或删除项

    • 示例:假设你有一个动态更新的字符串列表通过 ArrayAdapter 轻松地进行更新

      // 数据源
      List<String> items = new ArrayList<>();
      items.add("Item 1");
      items.add("Item 2");
      
      // 创建 ArrayAdapter
      ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, items);
      
      // 将 ArrayAdapter 设置为 ListView 的适配器
      ListView listView = findViewById(R.id.listView);
      listView.setAdapter(adapter);
      
      // 添加新项到数据源
      items.add("Item 3");
      adapter.notifyDataSetChanged(); // 通知适配器数据已更改
      

    总结

    • ArrayAdapter 的使用场景包括

      • 显示简单的文本列表(如城市名称、联系人列表等)

      • 显示单选项或复选项列表

      • 显示自定义对象列表(使用自定义布局)

      • 动态更新数据(添加、删除列表项)

    • 它适用于需要将简单数据源(如数组或列表)绑定到 ListViewGridView 等视图组件中的场景。如果你需要更复杂的视图或数据处理,可能需要使用 RecyclerView 和自定义 RecyclerView.Adapter

完整代码示例

  • 创建自定义类,例如:Item.java,它包含了列表项的文本图标资源 ID

    public class Item {
        private String text;	//文本
        private int iconResId;	//视图资源Id
    
        public Item(String text, int iconResId) {
            this.text = text;
            this.iconResId = iconResId;
        }
    
        public String getText() {
            return text;
        }
    
        public int getIconResId() {
            return iconResId;
        }
    }
    
  • 启动类中实操如下:准备一个包含 Item 对象的数据集合作为数据源

    List<Item> itemList = new ArrayList<Item>();	//创建自定义类'Item'的 ArrayList 类(纯文本列表可以省略)
    //定义数据源
    itemList.add(new Item("Apple", R.drawable.apple));	
    itemList.add(new Item("Banana", R.drawable.banana));
    itemList.add(new Item("Cherry", R.drawable.cherry));
    itemList.add(new Item("Date", R.drawable.date));
    itemList.add(new Item("Grape", R.drawable.grape));
    //纯文本列表:itemList.add("Grape");
    
  • 创建一个自定义的 ArrayAdapter 实例,用来管理 Item 对象的数据集合

    ArrayAdapter<Item> adapter = new ArrayAdapter<Item>(
            this,
            R.layout.item_listview, // 自定义的列表项布局文件,它包含一个 ImageView 和一个 TextView 用于显示 Item 对象的文本和图标(纯文本列表可以省略 ImageView 布局)
            itemList) {
        
        //在 ArrayAdapter 的匿名子类中重写了 getView 方法,以便自定义每个列表项的显示内容(纯文本列表可以省略,它会自动调用)
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // 重写getView方法以便自定义显示列表项
            if (convertView == null) {	//null,表示要获取一个新的视图对象
                convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_listview, parent, false);
            }
    
            ImageView iconImageView = convertView.findViewById(R.id.iconImageView);
            TextView textView = convertView.findViewById(R.id.textView);
    
            Item item = getItem(position);
    
            if (item != null) {	//不为null,则可以重复使用该视图对象,避免重复创建
                iconImageView.setImageResource(item.getIconResId());
                textView.setText(item.getText());
            }
    
            return convertView;
        }
    };
    
  • 创建一个自定义的列表项布局文件 item_listview.xml,用来显示每个 Item 对象的文本和图标:在布局文件中,我们使用了一个 ImageView 来显示图标,一个 TextView 来显示文本内容(纯文本列表可以省略 ImageView 布局

    <!-- item_listview.xml -->
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="16dp">
    
        <ImageView
            android:id="@+id/iconImageView"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:layout_marginEnd="16dp"
            android:src="@drawable/ic_launcher_foreground" />
    
        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="18sp"
            android:text="Item Text" />
    
    </LinearLayout>
    
  • 将创建的适配器绑定到 ListView 控件上

    ListView listView = findViewById(R.id.listView);
    listView.setAdapter(adapter);
    
  • 通过以上步骤,我们创建了一个带有自定义视图ArrayAdapter,它显示了每个 Item 对象的文本和图标。当 ListView 显示时,ArrayAdapter 将根据数据源中的 Item 对象动态创建或重用视图,并将相应的文本和图标显示在列表项中

posted @ 2024-07-31 11:47  阿俊学JAVA  阅读(248)  评论(0编辑  收藏  举报