Commonly used controls - list view

Article directory

1. List View Overview

1. Inheritance diagram

List view (ListView) inherits abstract list view (AbsListView), which in turn inherits adapter view (AdapterView). Adapter views have a common feature, which is to use the adapter to bind the data source to the display control.

2. Four elements of list view

element illustrate
List control Display multiple items for users
adapter Array adapter, simple adapter, cursor adapter, base adapter...
data source Arrays, lists, cursors...
List item template Platform resources, user customization
  • Four elements of list view: list control, adapter, list item template and data source

3. Four kinds of adapters

  • List View (ListView), which is the grandson class of AdapterView, uses the adapter as a bridge to bind data sources.
adapter meaning
ArrayAdapter array adapter
SimpleAdapter simple adapter
SimpleCursorAdapter Simple cursor adapter
BaseAdapter base adapter

2. Case of using list view based on array adapter - reading ancient poems

  • Brief description of the case: Contains two windows. The first window is a list of ancient poem titles for the user to choose. When the user clicks on an item, it immediately jumps to the second window, which displays the content (title, author, etc.) of the ancient poem selected by the user. , text), the second window has a return to table of contents button, click this button to return to the first window displaying the list of ancient poem titles.

1. Knowledge points involved

  • LinearLayout
  • Label(TextView)
  • Button
  • ListView
  • ArrayAdapter
  • Array or array list (Array | ArrayList)

2. Implementation steps

(1). Create Android application [ReadAncientPoetry]

  • Create an Android application based onEmpty ActivityReadAncientPoetry
    Insert image description here
  • Click the [finish] button

(2) Copy the background image to the drawable directory

  • Copy the background image todrawabledirectory
    Insert image description here

(3), String resource file

  • String resource filestrings.xml
    Insert image description here
  • View full code
<resources>
    <string name="app_name">阅读古诗</string>

    <string-array name="titles">
        <item>静夜思</item>
        <item>登鹳雀楼</item>
        <item>相思</item>
        <item>听弹琴</item>
        <item>登乐游原</item>
        <item>朝发白帝城</item>
        <item>巴山夜雨</item>
        <item>渭城曲</item>
        <item>春夜喜雨</item>
        <item>离离原上草</item>
        <item>示儿</item>
    </string-array>

    <string-array name="authors">
        <item>唐·李白</item>
        <item>唐·王之涣</item>
        <item>唐·王维</item>
        <item>唐·刘长卿</item>
        <item>唐·李商隐</item>
        <item>唐·李白</item>
        <item>唐·杜牧</item>
        <item>唐·王维</item>
        <item>唐·杜甫</item>
        <item>唐·白居易</item>
        <item>宋·陆游</item>
    </string-array>

    <string-array name="contents">
        <item>床前明月光,\n疑是地上霜。\n举头望明月,\n低头思故乡。</item>
        <item>白日依山尽,\n黄河入海流。\n欲穷千里目,\n更上一层楼。</item>
        <item>红豆生南国,\n春来发几枝。\n愿君多采撷,\n此物最相思。</item>
        <item>泠泠七弦上,\n静听松风寒。\n古调虽自爱,\n今人多不弹。</item>
        <item>向晚意不适,\n驱车登古原。\n夕阳无限好,\n只是近黄昏。</item>
        <item>朝辞白帝彩云间,\n千里江陵一日还。\n两岸猿声啼不住,\n轻舟已过万重山。</item>
        <item>君问归期未有期,\n巴山夜雨涨秋池。\n何当共剪西窗烛,\n却话巴山夜雨时。</item>
        <item>渭城朝雨浥轻尘,\n客舍青青柳色新。\n劝君更尽一杯酒,\n西出阳关无故人。</item>
        <item>好雨知时节,当春乃发生。\n随风潜入夜,润物细无声。\n野径云俱黑,江船火独明。\n晓看红湿处,花重锦官城。</item>
        <item>离离原上草,一岁一枯荣。\n野火烧不尽,春风吹又生。\n远芳侵古道,晴翠接荒城。\n又送王孙去,萋萋满别情。</item>
        <item>死去元知万事空,\n但悲不见九州同。\n王师北定中原日,\n家祭无忘告乃翁。 </item>
    </string-array>
</resources>

(4) Layout resource file activity_main.xml

  • layout resource fileactivity_mian.xml
    Insert image description here
  • View full code
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background"
    android:padding="15dp"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/lv_poem_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:divider="#aaaaaa"
        android:dividerHeight="0.5dp"/>

</LinearLayout>
  • View preview effect
    Insert image description here

(5) Create a poetry list template

  • Create a poetry list templatepoem_list_item.xml
    Insert image description here
    Insert image description here
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/tv_poem_title"
    android:gravity="center_vertical"
    android:minHeight="80dp"
    android:textColor="#0000ff"
    android:textSize="25sp">

</TextView>

(6), main interface class implementation function

  • Main interface class -MainActivity
    Insert image description here

  • declare variables
    Insert image description here

  • Get the control instance by resource identifier
    Insert image description here

  • Initialize the ancient poem title array
    Insert image description here

  • Create an array adapter as a bridge between list controls and data sources
    Insert image description here

  • Set adapter for list
    Insert image description here

  • Modify sliding effect
    Insert image description here

  • Modify the main interface class and register an item click listener for the list control
    Insert image description here

  • The parameter position is the position where the user clicked the list item, starting from 0. For example, if the user clicks the third list item, then the position is equal to 2. In other words, the position must be increased by 1 to determine the line number.

  • The value of parameter id is equal to the value of parameter position. The two parameters are just different types.

(7). Create an interface to display the content of ancient poems - ContentActivity

  • Content interface layout resource file -ContentActivity
    Insert image description here

(8), String resource file strings.xml

Insert image description here

(9) Content interface layout resource file

  • Open the content layout resource file -content_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_marginTop="30dp"
        android:layout_marginBottom="20dp"
        android:layout_weight="1"
        android:gravity="center_vertical"
        android:textColor="#ff00ff"
        android:textSize="40sp" />

    <TextView
        android:id="@+id/tv_author"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_marginBottom="20dp"
        android:layout_weight="1"
        android:gravity="center_vertical"
        android:textColor="#000000"
        android:textSize="25sp" />

    <TextView
        android:id="@+id/tv_content"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_marginBottom="20dp"
        android:layout_weight="8"
        android:textColor="#0000ff"
        android:textSize="30sp" />

    <Button
        android:id="@+id/btn_back"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:onClick="doBack"
        android:text="@string/back"
        android:textSize="20sp" />

</LinearLayout>

(10) Modify the main interface class and implement window instances

Insert image description here

(11) Modify the content interface and display ancient poems

Insert image description here

  • declare variables
    Insert image description here

  • Get the control instance by resource identifier
    Insert image description here

  • Obtain the intention of window jump, obtain the position carried by the intention, and perform corresponding processing
    Insert image description here

  • Write the [Return to Ancient Poetry Catalog] button click event processing method
    Insert image description here

  • Check the effect
    Insert image description here

list view

(12), View the final code

①Main interface class - MainActivity
package net.xyx.read_ancient_poetry;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private ListView lvPoemTitle;//诗歌标题列表控件 - 展示
    private ArrayAdapter<String> adapter;//数组适配器 - 桥梁
    private String[] titles;//诗歌标题数组 - 数据源


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //利用布局资源文件设置用户界面
        setContentView(R.layout.activity_main);

        //通过资源标识符获取控件实例
        lvPoemTitle = findViewById(R.id.lv_poem_title);

        //初始化古诗标题数组,作为列表控件的数据源
        titles = getResources().getStringArray(R.array.titles);
        //给古诗标题填上序号
        for (int i = 0; i < titles.length; i++){
            titles[i] = (i + 1) + "." + titles[i];
        }

        //创建数组适配器,作为连接列表控件与数据源的桥梁
        adapter = new ArrayAdapter<>(
                this,//上下文
                R.layout.poem_list_item,//列表项模板 - 平台布局资源
                titles //数据源 - 字符串数据组
        );

        //给列表控件设置适配器
        lvPoemTitle.setAdapter(adapter);

        //给列表控件注册项单击监听器
        lvPoemTitle.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(MainActivity.this,
                        "你选择了古诗[" + titles[position] + "]",
                        Toast.LENGTH_SHORT).show();

                //创建时新窗口跳转的意图
                Intent intent = new Intent(MainActivity.this, ContentActivity.class);
                //通过意图携带数据(选中的列表项位置)
                intent.putExtra("position",position);
                //按意图启动目标组件
                startActivity(intent);
            }
        });
    }
}
②Content interface - ContentActivity
package net.xyx.read_ancient_poetry;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class ContentActivity extends AppCompatActivity {

    private TextView tvTitle;//标题标签
    private TextView tvAuthor;//作者标签
    private TextView tvContent;//内容标签
    private String[] titles;//标题数组
    private String[] authors;//作者数组
    private String[] contents;//内容数组

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //利用布局资源文件设置用户界面
        setContentView(R.layout.activity_content);

        //通过资源标识符获取控件实例
        tvTitle = findViewById(R.id.tv_title);
        tvAuthor = findViewById(R.id.tv_author);
        tvContent = findViewById(R.id.tv_content);

        //获取窗口跳转的意图
        Intent intent = getIntent();
        //判断意图是否为空
        if (intent != null){
            //获取意图携带的数据
            int position = intent.getIntExtra("position",0);
            //获取古诗标题数组
            titles = getResources().getStringArray(R.array.titles);
            //获取古诗作者数组
            authors = getResources().getStringArray(R.array.authors);
            //获取古诗内容数组
            contents = getResources().getStringArray(R.array.contents);
            //设置标题标签文本
            tvTitle.setText(titles[position]);
            //设置作为标签文本
            tvAuthor.setText(authors[position]);
            //设置内容标签文本
            tvContent.setText(contents[position]);
        }
    }

    /**
     *
     * 【返回古诗目录】按钮单击事件处理方法
     * @param view
     */

    public void doBack(View view){
        finish();//关闭当前窗口
    }
}

3. Create a simple adapter

1. Simple adapter API documentation

https://developer.android.google.cn/reference/kotlin/android/widget/SimpleAdapter?hl=en
Insert image description here

2. Simple adapter inheritance diagram

  • The SimpleAdapter class inherits the BaseAdapter class

3. Simple adapter construction method

  • The simple adapter provides a constructor with 5 parameters

4. Custom adapter case - address book

(1). Create Android applications

  • Create an Android application based onEmpty Activity template - Contacts
    Insert image description here
  • Click the [finish] button
    Insert image description here

(2) Copy the picture material to the drawable directory

Insert image description here

(3), String resource file strings.xml

Insert image description here

<resources>
    <string name="app_name">通讯录</string>
    <string name="icon">图标</string>
    <string name="name">姓名</string>
    <string name="phone">电话</string>
</resources>

(4) Main layout resource file activity_main.xml

Insert image description here

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background"
    android:orientation="vertical"
    android:padding="10dp"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/tv_icon"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginRight="20dp"
            android:layout_weight="0.5"
            android:text="@string/icon"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/tv_name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/name"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/tv_phone"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1.5"
            android:text="@string/phone"
            android:textSize="20sp" />
    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_marginTop="5dp"
        android:layout_marginBottom="5dp"
        android:background="#aaaaaa" />

    <ListView
        android:id="@+id/lv_contact"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </ListView>

</LinearLayout>

(5) Contact list item template contact_list_item.xml

Insert image description here

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background"
    android:orientation="vertical"
    android:padding="10dp"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/tv_icon"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginRight="20dp"
            android:layout_weight="0.5"
            android:text="@string/icon"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/tv_name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/name"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/tv_phone"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1.5"
            android:text="@string/phone"
            android:textSize="20sp" />
    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_marginTop="5dp"
        android:layout_marginBottom="5dp"
        android:background="#aaaaaa" />

    <ListView
        android:id="@+id/lv_contact"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </ListView>

</LinearLayout>

(6), Main interface class - MainActivity

Insert image description here

  • declare variables
    Insert image description here
  • Get the control instance by resource identifier
    Insert image description here
  • Initialize contact list (data source)
  • Create a simple adapter as a bridge
    Insert image description here
  • Set up an adapter for the list control
    Insert image description here

(7), Main interface class MainActivity source code

package net.xyx.contacts;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private ListView lvContact; // 联系人列表控件(展示)
    private SimpleAdapter adapter; // 简单适配器(桥梁)
    private List<HashMap<String, Object>> contacts; // 联系人列表(数据源)

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 利用布局资源文件设置用户界面
        setContentView(R.layout.activity_main);
        // 通过资源标识符获取控件实例
        lvContact = findViewById(R.id.lv_contact);

        // 初始化联系人列表(数据源)
        contacts = getContacts();

        // 创建简单适配器作为桥梁
        adapter = new SimpleAdapter(
                this, // 上下文
                contacts, // 数据源(列表)
                R.layout.contact_list_item, // 列表项模板
                new String[] {"icon", "name", "phone"}, // 字段名数组
                new int[] {R.id.tv_icon, R.id.tv_name, R.id.tv_phone} // 控件标识数组
        );

        // 给列表控件设置适配器
        lvContact.setAdapter(adapter);
    }

    /**
     * @return 联系人列表
     */
    private List<HashMap<String, Object>> getContacts() {
        // 声明联系人列表
        List<HashMap<String, Object>> contacts = new ArrayList<>();

        // 声明联系人
        HashMap<String, Object> contact = null;

        // 创建第1个联系人
        contact = new HashMap<>();
        contact.put("icon", R.drawable.img1);
        contact.put("name", "李红梅");
        contact.put("phone", "15895953456");
        // 将联系人添加到联系人列表
        contacts.add(contact);

        // 创建第2个联系人
        contact = new HashMap<>();
        contact.put("icon", R.drawable.img2);
        contact.put("name", "王晓玲");
        contact.put("phone", "13956572345");
        // 将联系人添加到联系人列表
        contacts.add(contact);

        // 创建第3个联系人
        contact = new HashMap<>();
        contact.put("icon", R.drawable.img3);
        contact.put("name", "唐语涵");
        contact.put("phone", "15845891234");
        // 将联系人添加到联系人列表
        contacts.add(contact);

        // 创建第4个联系人
        contact = new HashMap<>();
        contact.put("icon", R.drawable.img4);
        contact.put("name", "佟大为");
        contact.put("phone", "13934345680");
        // 将联系人添加到联系人列表
        contacts.add(contact);

        // 创建第5个联系人
        contact = new HashMap<>();
        contact.put("icon", R.drawable.img5);
        contact.put("name", "钟小翠");
        contact.put("phone", "15890904520");
        // 将联系人添加到联系人列表
        contacts.add(contact);

        // 创建第6个联系人
        contact = new HashMap<>();
        contact.put("icon", R.drawable.img6);
        contact.put("name", "张三丰");
        contact.put("phone", "13890985670");
        // 将联系人添加到联系人列表
        contacts.add(contact);

        // 创建第7个联系人
        contact = new HashMap<>();
        contact.put("icon", R.drawable.img7);
        contact.put("name", "刘玉玲");
        contact.put("phone", "15895673450");
        // 将联系人添加到联系人列表
        contacts.add(contact);

        // 返回联系人列表
        return contacts;
    }
}

4. Custom adapter case - Contact person

1. Create an Android application

  • Create an Android app based onEmpty Activity - ContactList
    Insert image description here
  • Click the [finish] button
    Insert image description here

2. Copy the background image to the drawable directory

  • Copy the background image todrawabledirectory
    Insert image description here

3. String resource file

  • String resource file -string.xml
    Insert image description here
<resources>
    <string name="app_name">联系人(采用自定义适配器)</string>
    <string name="icon">图标</string>
    <string name="name">姓名</string>
    <string name="phone">电话</string>
</resources>

3. Main layout resource file activity_main.xml

  • layout resource fileactivity_mian.xml
    Insert image description here
<?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="match_parent"
    android:background="@drawable/background"
    android:padding="10dp"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/tv_icon"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginRight="20dp"
            android:layout_weight="0.5"
            android:text="@string/icon"
            android:textColor="#000000"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/tv_name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/name"
            android:textColor="#000000"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/tv_phone"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1.5"
            android:text="@string/phone"
            android:textColor="#000000"
            android:textSize="20sp" />
    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_marginTop="5dp"
        android:layout_marginBottom="5dp"
        android:background="#aaaaaa" />

    <ListView
        android:id="@+id/lv_contact"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>
  • View preview effect
    Insert image description here

5. Create a contact list item template

  • Create contact list item template -contact_list_item.xml
    Insert image description here
<?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="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:orientation="horizontal">

    <ImageView
        android:id="@+id/iv_icon"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_marginRight="10dp"
        android:scaleType="fitXY"
        android:src="@drawable/img1" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

    <TextView
        android:id="@+id/tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#0000ff"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/tv_phone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="70dp"
        android:textColor="#555555"
        android:textSize="16sp" />
        </LinearLayout>
    </LinearLayout>

</LinearLayout>

6. Create a contact entity class

  • Contact entity class -Contact
    Insert image description here
package net.xyx.contact_list;

/**
 * 功能:
 * 作者:肖宇轩
 * 日期:2022年11月28日
 */
public class Contact {
    private int icon;//联系人图片
    private String phone;//联系人电话
    public String name;//联系人姓名

    public int getIcon() {
        return icon;
    }

    public void setIcon(int icon) {
        this.icon = icon;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Contact{" +
                "icon=" + icon +
                ", phone='" + phone + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}

7. Create a contact adapter

  • Create Contact Adapter -ContactAdapter
    Insert image description here
  • Inherit the base adapter and implement four abstract methods empty
    Insert image description here
  • declare variables
    Insert image description here
  • Create constructor

8. Main interface class implementation function

  • Main interface class -MainActivity

Insert image description here

  • Method to get the number of list items -getCount()
    Insert image description here
  • Get list item identifier -getItem()
    Insert image description here
  • Get list item identifier method -getItrmld()
    Insert image description here
  • Get list item view method - getView() - Difficulty
    Insert image description here

8. Main interface functions

  • Main interface class -MainActivity
    Insert image description here
  • declare variables
    Insert image description here
  • Get the control instance by resource identifier
    Insert image description here
  • Create a method to get a list of contacts -getContacts()

Guess you like

Origin blog.csdn.net/m0_63887380/article/details/127957338