ListView是平常开发过程中使用的相当多的一个控件。虽然Android的API中已经提供了许多适配器(Adapter),比如ArrayAdapter,SimpleAdapter等,但大部分情况下,这些简单的适配器无法达到我们的设计要求。比如,在每个列表项中响应各自的按钮等控件的事件。这时候,就要我们自己定义我们所需要的适配器了。
废话不多说,接下来我们做个简单的通讯录的界面,每个联系人后面加一个按钮,相应点击事件。
首先,建立一个自定义列表项布局list_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/image_person"
android:background="#00000000"
android:layout_width="40dp"
android:layout_height="40dp" />
<LinearLayout
android:orientation="vertical"
android:paddingLeft="5dp"
android:layout_weight="5"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/name"
android:textSize="16sp"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/number"
android:textSize="16sp"
android:layout_marginTop="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<Button
android:id="@+id/button"
android:text="按钮"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
布局很简单,一张图片,2个文本显示联系人姓名和电话号码,最后放一个按钮。
接着,我们建立一个Person类表示联系人:
public class Person {
private String name;
private String number;
private Bitmap image;
public String getName() {
return name;
}
public String getNumber() {
return number;
}
public Bitmap getImage() {
return image;
}
public void setName(String name) {
this.name = name;
}
public void setNumber(String number) {
this.number = number;
}
public void setImage(Bitmap image) {
this.image = image;
}
}
之后就可以建立我们自己的适配器了,我们建立MyAdapter继承BaseAdpter,重写一下这些方法,最重要的就是getView()这个函数:
public class MyAdapter extends BaseAdapter {
private Context mContext;
//获得的联系人列表
private List<Person> list_info;
private LayoutInflater inflater;
class ViewHolder {
private ImageView image;
private TextView name, number;
private Button button;
}
public MyAdapter(Context mContext) {
this.mContext = mContext;
inflater = LayoutInflater.from(mContext);
list_info=new ArrayList<Person>();
}
public void setList_info( List<Person> list_info) {
this.list_info = list_info;
}
@Override
public int getCount() {
return list_info.size();
}
@Override
public Object getItem(int position) {
return list_info.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;
final Person person = list_info.get(position);
if (convertView == null) {
//设置列表布局
convertView=inflater.inflate(R.layout.list_item, null);
viewHolder = new ViewHolder();
//获取布局中的控件
viewHolder.image=(ImageView)convertView.findViewById(R.id.image_person);
viewHolder.name = (TextView) convertView.findViewById(R.id.name);
viewHolder.number = (TextView) convertView.findViewById(R.id.number);
viewHolder.button=(Button)convertView.findViewById(R.id.button);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
//初始化列表项
viewHolder.image.setImageBitmap(person.getImage());
viewHolder.name.setText(person.getName());
viewHolder.number.setText(person.getNumber());
//按钮的响应事件就随便写个简单显示Toast好了,如果想做复杂可以点击后切换到编辑联系人界面
viewHolder.button.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(mContext,"你按下了第"+position+"个标签上的按钮",Toast.LENGTH_SHORT)
.show();
}
});
return convertView;
}
}
最后,在MainAcitvity里读取联系人并初始化到自定义的适配器就可以了。
//这是读取联系人的函数,将读取的联系人保存到定义的List<Person> persons中
private void loadpersons() {
if (persons == null) {
persons = new ArrayList<Person>();
ContentResolver resolver = getContentResolver();
Cursor cursor = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Photo.PHOTO_ID,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID},
null, null, null);
if (cursor != null) {
while (cursor.moveToNext()) {
Person person = new Person();
person.setName(cursor.getString(cursor.getColumnIndex(ContactsContract.
CommonDataKinds.Phone.DISPLAY_NAME)));
person.setNumber(cursor.getString(cursor.getColumnIndex(ContactsContract.
CommonDataKinds.Phone.NUMBER)));
Long contactid = cursor.getLong(cursor.getColumnIndex(ContactsContract.
CommonDataKinds.Phone.CONTACT_ID));
Long photoid = cursor.getLong(cursor.getColumnIndex(ContactsContract.
CommonDataKinds.Phone.PHOTO_ID));
Bitmap image_person = null;
if (photoid > 0) {
Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI,
contactid);
InputStream inputStream = ContactsContract.Contacts.
openContactPhotoInputStream(resolver, uri);
image_person = BitmapFactory.decodeStream(inputStream);
}
person.setImage(image_person);
persons.add(person);
}
cursor.close();
}
}
}
//接着初始化适配器就OK了
private void setupComponent() {
list = (ListView) findViewById(R.id.list);
MyAdapter myAdapter = new MyAdapter(this);
//把读取的联系人列表放入适配器中
myAdapter.setList_info(persons);
list.setAdapter(myAdapter);
}
<uses-permission android:name="android.permission.READ_CONTACTS"/>