基于Java语言的安卓编程之二十六通信录读取(下)

时间:2021-08-25 00:47:56

2 适配器的定义

在“GetMyPhoneNumber->src->com.example.getmyphonenumber”包的右键菜单中选择“New->Class”,为项目添加一个名为“MyAdapter”的类,并且将该类的父类设置为BaseAdapter。

2.1 定义类的变量

为“MyAdapter”类添加两个变量:

    private List<PhoneInfo>lists;

    private Contextcontext;

其中,lists是自定义类PhoneInfo的列表,表示要显示的数据,即通信录中的数据;context是本程序的上下文。

2.2 定义类的构造函数

“MyAdapter”类的构造函数包含两个参数,分别为通信录的数据和上下文,并将这两参数分别赋值给类的变量:

    public MyAdapter(List<PhoneInfo> lists,Context context)

    {

       this.lists = lists;

       this.context = context;

    }

2.3 重载类的方法

自定义适配器类,需要重载父类的方法,包括getCount()、getItem()、getItemId()以及getView()等。

2.3.1 重载getCount()

getCount()方法的主要作用是获取适配器对应数据的数量。

    public int getCount() {

       returnlists.size();

    }

其中,lists是表示通信录数据的列表。

2.3.2 重载getItem()

getItem()的方法的主要作用获取适配器对应的数据。

    @Override

    public Object getItem(int positon) {

       returnlists.get(positon);

    }

其中,position是数据在列表中的位置。

2.3.3 重载getItemId()

getItemId()方法的主要作用是获取数据的位置。

    @Override

    public long getItemId(int position) { 

  return position;

    }

2.3.4 重载getView()

当显示ListView中某项时,就会调用适配器的getView()方法。该方法的作用是设置ListView项的布局及显示内容,关于该方法的讲解见“基于Java语言的安卓编程之十五自动完成文本框”。

重载getView()方法的格式为

    @Override
public ViewgetView(int position, View convertView, ViewGroup parent)

 {

........

}

(1)创建界面布局文件

在ListView中使用适配器时,需要将ListView的项与界面布局文件进行关联。ListView的项用来显示通信录中的名称和号码,包含两个TextView控件,并且需要将布局的orientation设置为horizontal。

在“GetMyPhoneNumber->res->layout”的右键菜单中,选择“New->AndroidXML File”新建一个类型为LinearLayout的界面布局文件,并将其命名为“call.xml”。

在该文件中设置布局的orientation及控件。

(2)定义视图容器类

由于在getView()方法中要同时使用到表示姓名和号码的两个TextView控件,为了表示方便,自定义一个名为“HolderView”的类,表示这两个TextView控件。

在MyAdapter类的定义中添加“HolderView”类的定义。

    private static class ViewHolder{

       TextView tvName;

       TextView tvNumber;

    }

其中,tvName表示显示通信录中姓名的TextView控件,tvNumber表示显示通信录中号码的TextView控件。

(3)导入界面布局文件

在getView()方法中导入创建的界面布局文件“call.xml”。

1 if(convertView==null)

2 {

3   convertView = LayoutInflater.from(context).inflate(R.layout.call,null);

4   holder= new ViewHolder();

5   holder.tvName =(TextView)convertView.findViewById(R.id.tv_Name);

6   holder.tvNumber=(TextView)convertView.findViewById(R.id.tv_Number);

7   convertView.setTag(holder);

8 }

第1行表示判断ListView的项是否第一次显示(详见“基于Java语言的安卓编程之十五自动完成文本框”)。如果convertView为null,则表示是第一次显示,第3行代码导入了在(1)中创建的界面布局文件;第4-7行创建了自定义ViewHolder类的对象holder,holder在if语句之外定义

ViewHolder holder;

将该对象的两个TextView控件赋值为call.xml中定义的两个控件之后,通过setTag()方法将其加入到convertView中,目的是为了当ListView的项不是第一次显示时,不需要再次导入界面布局文件,直接获得该界面布局文件中的两个控件,该代码在(4)中介绍。

(4)直接获取控件

如果ListView的项不是第一次显示,则通过convertView直接获取布局文件中的两个控件。

       else

       {

           holder = (ViewHolder)convertView.getTag();

       }

其中getTag()方法获取到的就是在(3)中使用setTag()加入到convertView中的自定义类ViewHolder的对象,通过该对象就可以获取到布局文件中的两个控件。

(5)设置控件显示内容

在获取到了布局界面中的两个控件之后,将适配器中的数据显示在控件中。

holder.tvName.setText(lists.get(position).getPhoneName());

    holder.tvNumber.setText(lists.get(position).getPhoneNumber());

其中,lists是适配器中表示通信录的数据,position是getView()方法的参数,表示数据在列表中的位置,通过List类的get()方法获取到的列表中的元素类型是自定义类PhoneInfo,在通过该类的getPhoneName()方法和getPhoneNumber()方法获取通信录中的姓名和号码;通过setText()方法显示在TextView控件中。

3 ListView的创建及适配器的设置

3.1 创建ListView

在程序主界面布局文件中添加ListView控件。

3.2 设置适配器

在MainActivity()的onCreate()方法中,首先调用GetNumber类的静态方法getNumber()来获取通信录中的数据。

GetNumber.getNumber(this);

之后创建适配器

adapter = new MyAdapter(GetNumber.lists,this);

其中,MyAdapter是在“2 适配器的定义”中自定义的适配器,该适配器构造函数的第一个参数是GetNumber类的lists变量,该变量即为获取到的通信录的数据,第二个参数this表示本应用程序的上下文。

最后,将适配器与ListView控件关联。

listView.setAdapter(adapter);

其中,listView是程序主界面布局中的ListView控件。

4 小结

今天学习了显示安卓系统中通信录的方法。首先通过ContentResolver类访问通信录,并通过Cursor接口遍历通信录中的数据;通过自定义适配器将通信录数据与ListView项布局中的控件关联起来,最后设置ListView控件的适配器即可显示本机的通信录。