2 适配器的定义
在“GetMyPhoneNumber->src->com.example.getmyphonenumber”包的右键菜单中选择“New->Class”,为项目添加一个名为“MyAdapter”的类,并且将该类的父类设置为BaseAdapter。
2.1 定义类的变量
为“MyAdapter”类添加两个变量:
private List<PhoneInfo> lists;
private Context context;
其中,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() {
return lists.size();
}
其中,lists是表示通信录数据的列表。
2.3.2 重载getItem()
getItem()的方法的主要作用获取适配器对应的数据。
@Override
public Object getItem(int positon) {
return lists.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控件的适配器即可显示本机的通信录。