Android自定义适配器BaseAdapter
在开发中,我们经常使用到ListView这个控件。Android的API也提供了许多创建ListView适配器的快捷方式。例如ArrayAdapter、SimpleAdapter和SimpleCursorAdapter等。但你是否发现,如果采用这些系统自带的适配器,对于事件的响应只能局限在一个行单位。假设一行里面有一个按钮和一个图片控件,它们之间的响应操作是不一样的。若采用系统自带的适配器,就不能精确到每个控件的响应事件。这时,我们一般采取自定义适配器来实现这个比较精确地请求。
ListView的创建,一般要具备两大元素:
1)数据集,即要映射的字符串、图片信息之类。
2)适配器,实现把要映射的字符串、图片信息映射成视图(如Textview、Image等组件),再添加到ListView中。
下面是一个实操例子:
实现细节:
1、创建数据集,一般定义如下
private List<Map<String, Object>> listItems;
元素添加方式:
Map<String, Object> map = new HashMap<String, Object>();
map.put("image", imgeIDs[i]); //图片资源
map.put("title", "物品名称:"); //物品标题
map.put("info", goodsNames[i]); //物品名称
map.put("detail", goodsDetails[i]); //物品详情
listItems.add(map); //添加一项
2、创建适配器
public class ListViewAdapter extends BaseAdapter{........} //自定义的适配器一般继承BaseAdapter类
listViewAdapter = new ListViewAdapter(this, listItems);
3、给ListView设置适配器
listView.setAdapter(listViewAdapter);
4、这里还有个关键点,如何把list_item.xml布局作为一个视图,添加到listView中:
LayoutInflater listContainer; //视图容器工厂
listContainer = LayoutInflater.from(context); //创建视图容器工厂并设置上下文
convertView = listContainer.inflate(R.layout.list_item, null); //创建list_item.xml布局文件的视图
实例视图如下:
1)布局文件main.xml
1. <?xml version="1.0" encoding="utf-8"?>
2. <LinearLayout xmlns:Android="http://schemas.android.com/apk/res/android"
3. Android:orientation="vertical"
4. Android:layout_width="fill_parent"
5. Android:layout_height="fill_parent">
6.
7. <!-- 结算 -->
8. <LinearLayout Android:gravity="center_horizontal"
9. Android:orientation="horizontal" android:layout_width="fill_parent"
10. Android:layout_height="wrap_content">
11. <TextView Android:text="结算: "
12. Android:layout_width="wrap_content"
13. Android:layout_height="wrap_content"
14. Android:textColor="#FFFFFFFF"
15. Android:textSize="20px"/>
16. <ImageButton Android:id="@+id/imgbt_sum"
17. Android:layout_width="40px"
18. Android:layout_height="40px"
19. Android:background = "@drawable/shopping" />
20. </LinearLayout>
21.
22. <TextView Android:text="商品列表: "
23. Android:layout_width="wrap_content"
24. Android:layout_height="wrap_content"
25. Android:textColor="#FFFFFFFF" />
26.
27. <!-- 商品列表 -->
28. <ListView Android:id="@+id/list_goods"
29. Android:layout_width="fill_parent"
30. Android:layout_height="wrap_content" />
31.
32. </LinearLayout>
列表项布局文件list_item.xml
1. <?xml version="1.0" encoding="utf-8"?>
2. <LinearLayout xmlns:Android="http://schemas.android.com/apk/res/android"
3. Android:orientation="horizontal" android:layout_width="fill_parent"
4. Android:layout_height="fill_parent">
5.
6. <!-- 商品图片 -->
7. <ImageView Android:id="@+id/imageItem"
8. Android:layout_width="wrap_content"
9. Android:layout_height="wrap_content"
10. Android:layout_margin="5px"/>
11.
12. <!-- 商品信息 -->
13. <LinearLayout Android:orientation="vertical"
14. Android:layout_width="wrap_content"
15. Android:layout_height="wrap_content">
16.
17. <TextView Android:id="@+id/titleItem"
18. Android:layout_width="wrap_content"
19. Android:layout_height="wrap_content"
20. Android:textColor="#FFFFFFFF"
21. Android:textSize="13px" />
22. <TextView Android:id="@+id/infoItem"
23. Android:layout_width="wrap_content"
24. Android:layout_height="wrap_content"
25. Android:textColor="#FFFFFFFF"
26. Android:textSize="22px" />
27. </LinearLayout>
28.
29. <!-- 购买和商品详情 -->
30. <LinearLayout Android:gravity="right"
31. Android:orientation="horizontal" android:layout_width="fill_parent"
32. Android:layout_height="wrap_content">
33. <CheckBox Android:id="@+id/checkItem"
34. Android:layout_width="wrap_content"
35. Android:layout_height="wrap_content"
36. Android:layout_margin="5px"/>
37. <Button Android:id="@+id/detailItem"
38. Android:layout_width="wrap_content"
39. Android:layout_height="wrap_content"
40. Android:layout_margin="5px"/>
41. </LinearLayout>
42. </LinearLayout>
2)代码,主代码:
1. package com.myAndroid.test;
2.
3. import java.util.ArrayList;
4. import java.util.HashMap;
5. import java.util.List;
6. import java.util.Map;
7.
8. import Android.app.Activity;
9. import Android.app.AlertDialog;
10. import Android.content.DialogInterface;
11. import Android.os.Bundle;
12. import Android.view.View;
13. import Android.view.View.OnClickListener;
14. import Android.widget.ArrayAdapter;
15. import Android.widget.ImageButton;
16. import Android.widget.ListView;
17.
18. public class MyListView extends Activity {
19.
20. private ListView listView;
21. private ImageButton imgbt_sum;
22. private ListViewAdapter listViewAdapter;
23. private List<Map<String, Object>> listItems;
24. private Integer[] imgeIDs = {R.drawable.cake,
25. R.drawable.gift, R.drawable.letter,
26. R.drawable.love, R.drawable.mouse,
27. R.drawable.music};
28. private String[] goodsNames = { "蛋糕", "礼物",
29. "邮票", "爱心", "鼠标", "音乐CD"};
30. private String[] goodsDetails = {
31. "蛋糕:好好吃。",
32. "礼物:礼轻情重。",
33. "邮票:环游世界。",
34. "爱心:世界都有爱。",
35. "鼠标:反应敏捷。",
36. "音乐CD:酷我音乐。"};
37.
38. /** Called when the activity is first created. */
39. @Override
40. public void onCreate(Bundle savedInstanceState) {
41. super.onCreate(savedInstanceState);
42. setContentView(R.layout.main);
43.
44. listView = (ListView)findViewById(R.id.list_goods);
45. imgbt_sum = (ImageButton) findViewById(R.id.imgbt_sum);
46. imgbt_sum.setOnClickListener(new ClickEvent());
47. listItems = getListItems();
48. listViewAdapter = new ListViewAdapter(this, listItems); //创建适配器
49. listView.setAdapter(listViewAdapter);
50. }
51.
52. /**
53. * 初始化商品信息
54. */
55. private List<Map<String, Object>> getListItems() {
56. List<Map<String, Object>> listItems = new ArrayList<Map<String, Object>>();
57. for(int i = 0; i < goodsNames.length; i++) {
58. Map<String, Object> map = new HashMap<String, Object>();
59. map.put("image", imgeIDs[i]); //图片资源
60. map.put("title", "物品名称:"); //物品标题
61. map.put("info", goodsNames[i]); //物品名称
62. map.put("detail", goodsDetails[i]); //物品详情
63. listItems.add(map);
64. }
65. return listItems;
66. }
67.
68. class ClickEvent implements OnClickListener{
69.
70. @Override
71. public void onClick(View v) {
72. // TODO Auto-generated method stub
73. String goodsList = "";
74. for(int i = 0; i < listItems.size(); i++) {
75. goodsList += listViewAdapter.hasChecked(i)? goodsNames[i] + " ": "";
76. }
77. new AlertDialog.Builder(MyListView.this)
78. .setTitle("购物清单:")
79. .setMessage("你好,你选择了如下商品:\n" + goodsList)
80. .setPositiveButton("确定", null)
81. .show();
82. }
83.
84. }
85. }
适配器代码:
1. package com.myAndroid.test;
2.
3. import java.util.List;
4. import java.util.Map;
5.
6. import Android.app.AlertDialog;
7. import Android.content.Context;
8. import Android.util.Log;
9. import Android.view.LayoutInflater;
10. import Android.view.View;
11. import Android.view.ViewGroup;
12. import Android.widget.BaseAdapter;
13. import Android.widget.Button;
14. import Android.widget.CheckBox;
15. import Android.widget.CompoundButton;
16. import Android.widget.ImageView;
17. import Android.widget.ListView;
18. import Android.widget.TextView;
19.
20. public class ListViewAdapter extends BaseAdapter {
21. private Context context; //运行上下文
22. private List<Map<String, Object>> listItems; //商品信息集合
23. private LayoutInflater listContainer; //视图容器
24. private boolean[] hasChecked; //记录商品选中状态
25. public final class ListItemView{ //自定义控件集合
26. public ImageView image;
27. public TextView title;
28. public TextView info;
29. public CheckBox check;
30. public Button detail;
31. }
32.
33.
34. public ListViewAdapter(Context context, List<Map<String, Object>> listItems) {
35. this.context = context;
36. listContainer = LayoutInflater.from(context); //创建视图容器并设置上下文
37. this.listItems = listItems;
38. hasChecked = new boolean[getCount()];
39. }
40.
41. public int getCount() {
42. // TODO Auto-generated method stub
43. return listItems.size();
44. }
45.
46. public Object getItem(int arg0) {
47. // TODO Auto-generated method stub
48. return null;
49. }
50.
51. public long getItemId(int arg0) {
52. // TODO Auto-generated method stub
53. return 0;
54. }
55.
56. /**
57. * 记录勾选了哪个物品
58. * @param checkedID 选中的物品序号
59. */
60. private void checkedChange(int checkedID) {
61. hasChecked[checkedID] = !hasChecked[checkedID];
62. }
63.
64. /**
65. * 判断物品是否选择
66. * @param checkedID 物品序号
67. * @return 返回是否选中状态
68. */
69. public boolean hasChecked(int checkedID) {
70. return hasChecked[checkedID];
71. }
72.
73. /**
74. * 显示物品详情
75. * @param clickID
76. */
77. private void showDetailInfo(int clickID) {
78. new AlertDialog.Builder(context)
79. .setTitle("物品详情:" + listItems.get(clickID).get("info"))
80. .setMessage(listItems.get(clickID).get("detail").toString())
81. .setPositiveButton("确定", null)
82. .show();
83. }
84.
85.
86. /**
87. * ListView Item设置
88. */
89. public View getView(int position, View convertView, ViewGroup parent) {
90. // TODO Auto-generated method stub
91. Log.e("method", "getView");
92. final int selectID = position;
93. //自定义视图
94. ListItemView listItemView = null;
95. if (convertView == null) {
96. listItemView = new ListItemView();
97. //获取list_item布局文件的视图
98. convertView = listContainer.inflate(R.layout.list_item, null);
99. //获取控件对象
100. listItemView.image = (ImageView)convertView.findViewById(R.id.imageItem);
101. listItemView.title = (TextView)convertView.findViewById(R.id.titleItem);
102. listItemView.info = (TextView)convertView.findViewById(R.id.infoItem);
103. listItemView.detail= (Button)convertView.findViewById(R.id.detailItem);
104. listItemView.check = (CheckBox)convertView.findViewById(R.id.checkItem);
105. //设置控件集到convertView
106. convertView.setTag(listItemView);
107. }else {
108. listItemView = (ListItemView)convertView.getTag();
109. }
110.// Log.e("image", (String) listItems.get(position).get("title")); //测试
111.// Log.e("image", (String) listItems.get(position).get("info"));
112.
113. //设置文字和图片
114. listItemView.image.setBackgroundResource((Integer) listItems.get(
115. position).get("image"));
116. listItemView.title.setText((String) listItems.get(position)
117. .get("title"));
118. listItemView.info.setText((String) listItems.get(position).get("info"));
119. listItemView.detail.setText("商品详情");
120. //注册按钮点击时间爱你
121. listItemView.detail.setOnClickListener(new View.OnClickListener() {
122. @Override
123. public void onClick(View v) {
124. //显示物品详情
125. showDetailInfo(selectID);
126. }
127. });
128. // 注册多选框状态事件处理
129. listItemView.check
130. .setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() {
131. @Override
132. public void onCheckedChanged(CompoundButton buttonView,
133. boolean isChecked) {
134. //记录物品选中状态
135. checkedChange(selectID);
136. }
137. });
138.
139. return convertView;
140. }
141.}
至于,如何实现系统自带的适配器,如ArrayAdapter、SimpleAdapter和SimpleCursorAdapter等,有机会再补充。
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。