首先,我们常用的Adapter有四种,分别是BaseAdapter、SimpleAdapter、ArrayAdapter、SimpleCursorAdapter四种。
BaseAdapter:基础数据适配器,它的主要用途是将一组数据传到例如ListView等UI显示组件,继承自接口类Adapter,由于是基础类型,所以自由度高, 可以修改的地方多。
SimpleAdapter:简单适配器,系统自定义了一些方法,可以重写这些方法。
ArrayAdapter:数据和UI一对一,传入数据源和布局文件,完成显示。
SimpleCursorAdapter:指向性适配器,指向数据库,可以方便地把数据库的内容以列表的形式展示出来
下面我们来介绍一下这四种Adapter的用法:
1.ArrayAdapter:
简单的ArrayAdapter,这样的列表的每一行都只有一行文字。
// 当然listview 也可以是在layout里写好,然后findViewById()获取出来,这样的话后面就不需setContentView(listview);
ListView listview = new ListView(this);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_expandable_list_item_1);
adapter.add("string1");
adapter.add("haha");
adapter.add("heihei");
listview.setAdapter(adapter);
setContentView(listview);
2.BaseAdapter:
publicclass MyListViewBase extends Activity {
private ListView lv;
//定义一个动态数组
ArrayList<HashMap<String, Object>>listItem;/** Called when the activity is first created. */
@Override
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lv = (ListView) findViewById(R.id.lv);
MyAdapter mAdapter = new MyAdapter(this);//得到一个MyAdapter对象
lv.setAdapter(mAdapter);//为ListView绑定Adapter
/**为ListView添加点击事件*/
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
publicvoid onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {
Log.v("MyListViewBase", "你点击了ListView条目" + arg2);//在LogCat中输出信息
}
});
}
/**添加一个得到数据的方法,方便使用*/
private ArrayList<HashMap<String, Object>> getDate(){
ArrayList<HashMap<String, Object>> listItem = new ArrayList<HashMap<String,Object>>();
/**为动态数组添加数据*/
for(int i=0;i<30;i++)
{
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("ItemTitle", "第"+i+"行");
map.put("ItemText", "这是第"+i+"行");
listItem.add(map);
}
return listItem;
}
/** 新建一个类继承BaseAdapter,实现视图与数据的绑定
*/
privateclass MyAdapter extends BaseAdapter {
private LayoutInflater mInflater;//得到一个LayoutInfalter对象用来导入布局
/**构造函数*/
public MyAdapter(Context context) {
this.mInflater = LayoutInflater.from(context);
}
@Override
publicint getCount() {
return getDate().size();//返回数组的长度
}
@Override
public Object getItem(int position) {
returnnull;
}
@Override
publiclong getItemId(int position) {
return 0;
}
/**书中详细解释该方法*/
@Override
public View getView(finalint position, View convertView, ViewGroup parent) {
ViewHolder holder;
//观察convertView随ListView滚动情况
Log.v("MyListViewBase", "getView " + position + " " + convertView);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item,null);
holder = new ViewHolder();
/**得到各个控件的对象*/
holder.title = (TextView) convertView.findViewById(R.id.ItemTitle);
holder.text = (TextView) convertView.findViewById(R.id.ItemText);
holder.bt = (Button) convertView.findViewById(R.id.ItemButton);
convertView.setTag(holder);//绑定ViewHolder对象
}
else{
holder = (ViewHolder)convertView.getTag();//取出ViewHolder对象
}
/**设置TextView显示的内容,即我们存放在动态数组中的数据*/
holder.title.setText(getDate().get(position).get("ItemTitle").toString());
holder.text.setText(getDate().get(position).get("ItemText").toString());
/**为Button添加点击事件*/
holder.bt.setOnClickListener(new OnClickListener() {
@Override
publicvoid onClick(View v) {
Log.v("MyListViewBase", "你点击了按钮" + position);//打印Button的点击信息
}
});
return convertView;
}
}
/**存放控件*/
publicfinalclass ViewHolder{
public TextView title;
public TextView text;
public Button bt;
}
}
还需要注意的是,Button会抢夺ListView的焦点,需要将Button设置为没有焦点。设置非常简单,只需要在xml的Button标签下加入一行:Android:focusable=“false”代码就可以了。在LogCat观察点击后输出的信息,运行效果如图所示:
3.SimpleAdapter:
ListView可以使用最基本的ArrayAdapter填充,但是每一行只能填充文本。我们的聊天内容除了文本,还希望有个头像(当然后期还可以再添聊天时间、用户名之类的~),首相想到的是使用SimpleAdapter。
这是第一个Demo的代码:
1. public class TryChatPopActivity extends Activity {
2. ListView itemlist = null;
3. List<Map<String, Object>> list;
4.
5. public void onCreate(Bundle savedInstanceState) {
6. super.onCreate(savedInstanceState);
7. setContentView(R.layout.main);
8. itemlist = (ListView) findViewById(R.id.chatlist);
9. refreshListItems();
10. }
11. private void refreshListItems() {
12. list = buildListForSimpleAdapter();
13. //实例适配器
14. SimpleAdapter chat = new SimpleAdapter(this, list, R.layout.chata,
15. new String[] {"chatportrait","chatinfo"}, new int[] {R.id.imgPortraitA,R.id.txvInfo});
16. itemlist.setAdapter(chat);
17. itemlist.setSelection(0);
18. }
19.
20. //用来实例化列表容器的函数
21. private List<Map<String, Object>> buildListForSimpleAdapter() {
22. List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(2);
23. ImageView imgA=(ImageView)findViewById(R.id.imgPortraitA);
24. //向列表容器中添加数据(每列中包括一个头像和聊天信息)
25. Map<String, Object> map = new HashMap<String, Object>();
26. map.put("chatportrait",imgA);
27. map.put("chatinfo", "嗨~");
28. list.add(map);
29.
30. map = new HashMap<String, Object>();
31. map.put("chatportrait",imgA);
32. map.put("chatinfo", "嗨~\n你好!");
33. list.add(map);
34.
35. map = new HashMap<String, Object>();
36. map.put("chatportrait",imgA);
37. map.put("chatinfo", "嗨~\n你好!\n我是小魏~");
38. list.add(map);
39.
40. return list;
41. }
42. }
其中 chata 布局文件如下:
1. <?xml version="1.0" encoding="utf-8"?>
2. <LinearLayout
3. xmlns:android="http://schemas.android.com/apk/res/android"
4. android:layout_width="fill_parent"
5. android:layout_height="wrap_content"
6. android:orientation="horizontal"
7. android:paddingTop="5px"
8. >
9. <ImageView
10. android:layout_width="42px"
11. android:layout_height="42px"
12. android:layout_gravity="bottom"
13. android:id="@+id/imgPortraitA"
14. android:background="@drawable/portraita"
15. />
16. <TextView android:id="@+id/txvInfo"
17. android:layout_width="wrap_content"
18. android:layout_height="wrap_content"
19. android:paddingTop="5px"
20. android:paddingBottom="5px"
21. android:paddingLeft="5px"
22. android:textColor="@android:color/black"
23. android:textSize="18dip"
24. android:background="@drawable/chatbg"></TextView>
25. </LinearLayout>
这里最关键是尝试定义和使用SimpleAdapter适配器:
SimpleAdapter chat = new SimpleAdapter(this, list, R.layout.chata, new String[] {"chatportrait","chatinfo"}, new int[] {R.id.imgPortraitA,R.id.txvInfo});
其中第一个参数是context,即当前的Activity;第二个参数是要去填充ListView每一行内容的list;第三个参数resource是ListView每一行填充的布局文件。
比较麻烦的是第四个和第五个参数,SimpleAdapter构造函数中第四个参数String[] from表示名字数组,因为在ArrayList存放的都是Map<String,Object>的item,from中的名字就是为了索引ArrayList中的Object。
第五个参数在构造函数中表示为int[] to,是索引layout中的id,对应前面每项的布局格式。
4. SimpleCursorAdapter
1 packagecom.example.simplecursoradapter;
2
3 import android.app.Activity;
4 import android.content.Intent;
5 import android.database.Cursor;
6 import android.database.CursorWrapper;
7 import android.graphics.Color;
8 import android.net.Uri;
9 import android.os.Bundle;
10 importandroid.provider.Contacts.People;
11 importandroid.telephony.PhoneNumberUtils;
12 import android.util.Log;
13 import android.view.View;
14 importandroid.widget.AdapterView;
15 import android.widget.LinearLayout;
16 importandroid.widget.ListAdapter;
17 importandroid.widget.ListView;
18 importandroid.widget.SimpleCursorAdapter;
19
20
21 publicclassMainActivity extendsActivity {
22 privatestatic final StringTAG = "MainActivity";
23
24
25
26 @Override
27 publicvoid onCreate(BundlesavedInstanceState) {
28 super.onCreate(savedInstanceState);
29
30 LinearLayout linearLayout =new LinearLayout(this);
31 linearLayout.setOrientation(LinearLayout.VERTICAL);
32
33 LinearLayout.LayoutParams param =newLinearLayout.LayoutParams(
34 LinearLayout.LayoutParams.FILL_PARENT,
35 LinearLayout.LayoutParams.WRAP_CONTENT);
36
37 listView = newListView(this);
38 linearLayout.addView(listView, param);
39 this.setContentView(linearLayout);
40
41 // 从数据库获取联系人姓名和电话号码
42 Cursor cur = this.getContentResolver().query(People.CONTENT_URI,null,
43 null,null, null);
44 adapter = newSimpleCursorAdapter(this,
45 android.R.layout.simple_list_item_2, cur,new String[] {
46 People.NAME,People.NUMBER },new int[] {
47 android.R.id.text1,android.R.id.text2 });
48 this.startManagingCursor(cur);
49 listView.setAdapter(adapter);
50
51 listView.setOnItemClickListener(newAdapterView.OnItemClickListener() {
52
53 publicvoid onItemClick(AdapterView<?> arg0, View arg1,
54 intposition, long arg3){
55
56
//
names=((CursorWrapper)listView.getItemAtPosition(position)).getColumnNames();
57 // 从指针的封装类中获得选中项的电话号码并拨号
58 CursorWrapper wrapper = (CursorWrapper) listView
59 .getItemAtPosition(position);
60 intcolumnIndex = wrapper.getColumnIndex(People.NUMBER);
61 if(!wrapper.isNull(columnIndex)) {
62 String number = wrapper.getString(columnIndex);
63 Log.d(TAG,"number=" + number);
64 //判断电话号码的有效性
65 if (PhoneNumberUtils.isGlobalPhoneNumber(number)) {
66 Intent intent =new Intent(Intent.ACTION_DIAL,Uri
67 .parse("tel://" + number));
68 startActivity(intent);
69 }
70 }
71 }
72 });
73 }
74
不要忘记添加权限:
<intent-filter>
<actionandroid:name="android.Intent.Action.CALL_BUTTON"/>
<categoryandroid:name="android.Intent.Category.DEFAULT"/>
</intent-filter>
<uses-permissionandroid:name="android.permission.READ_CONTACTS"/>