图片见附件
项目需要展示一个通讯簿,通讯簿中的手机号码是分组的,要求勾选组时,自动勾选组下的手机号码,实现效果如下:
我们这个实例主要讲的就是当点击一个分组的时候,分组里的所有人就默认的全部选中,有了这个功能我们在群发的时候就会给我们省去不少麻烦,这样我们就可以不用一个一个的选中了。那么我们就来看看这个效果是怎么样实现吗。
下面是实现步骤。
1、新建类PhoneListItem,用于表示分组中的每一个手机号码。
Java代码:
下载附件 (36.65 KB)
下载附件 (36.65 KB)
1. package eoe.ydtf.android;
2.
3. public class PhoneListItem {
4.
5. public String phone,name;
6.
7. public boolean checked;
8.
9. public PhoneListItem(String _name,String _phone,boolean _checked){
10.
11. name=_name;
12.
13. phone=_phone;
14.
15. checked=_checked;
16.
17. }
18.
19. }
复制代码
2、新建布局文件phone_list_item.xml,用于定义分组下面的每一条手机记录的页面布局。
Java代码:
1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2.
3. android:layout_width="fill_parent"
4. android:layout_height="wrap_content"
5. android:orientation="horizontal"
6. android:minHeight="40px"
7. android:layout_gravity="center_vertical">
8.
9. <CheckBox
10. android:id="@+id/phone_check"
11. android:focusable="false"
12. android:layout_width="wrap_content"
13. android:layout_height="wrap_content"
14. android:layout_marginLeft="35px"
15. android:checked="false"/>
16.
17. <TextView
18. android:id="@+id/phone_name"
19. android:layout_width="80dip"
20. android:layout_height="wrap_content"
21. android:layout_gravity="center_vertical" />
22.
23. <TextView
24. android:id="@+id/phone_number"
25. android:layout_width="wrap_content"
26. android:layout_height="wrap_content"
27. android:textColor="?android:attr/textColorPrimary"
28. android:paddingLeft="10px"
29. android:layout_gravity="center_vertical" />
30.
31. </LinearLayout>
复制代码
这个主要就是我们在这里布局,你想要什么样的效果都可以,这里就是上面效果图的布局
3、新建类PhoneGroup,用于表示一个分组。代码当中主要就是在一个分组里的内容,我们在用一个boolean值,这个就是说当你选中的时候是真,当你没有选中的时候是假,所以这个很主要,有了boolean值才能知道你是否选中。
Java代码:
1. import java.util.List;
2.
3. public class PhoneGroup {
4.
5. public String title;
6.
7. private boolean checked;
8.
9. public List<PhoneListItem> children;
10.
11. public PhoneGroup(String title,boolean checked,List<PhoneListItem> children){
12.
13. this.title=title;
14.
15. setChecked(checked);
16.
17. this.children=children;
18.
19. }
20.
21. public boolean getChecked(){
22.
23. return checked;
24.
25. }
26.
27. public void setChecked(boolean b){
28.
29. checked=b;
30.
31. if(children!=null&&children.size()>0){//若children不为空,循环设置children的checked
32.
33. for(PhoneListItem each : children){
34.
35. each.checked=checked;
36.
37. }
38.
39. }
40.
41. }
42.
43. }
复制代码
4、新建Activity布局文件phone_browser.xml,用于定义通讯簿的展现页面。
Java代码:
1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2.
3. android:layout_width="fill_parent"
4. android:layout_height="fill_parent"
5. android:orientation="vertical">
6.
7. <ExpandableListView
8. android:id="@+id/phonelist"
9. android:layout_width="fill_parent"
10. android:layout_height="0dip"
11. android:layout_weight="1" />
12.
13. </LinearLayout>
复制代码
5、新建类QxtPhoneSelect,用于呈现通讯簿的Activity页面。
Java代码:
1. package eoe.ydtf;
2.
3. import java.util.ArrayList;
4. import java.util.List;
5. import com.ydtf.android.PhoneGroupAdapter.ExpandableListHolder;
6. import android.app.Activity;
7. import android.os.Bundle;
8. import android.view.View;
9.
10. import android.widget.ExpandableListView;
11.
12. public class QxtSelectPhone extends Activity implements
13.
14. ExpandableListView.OnGroupClickListener,ExpandableListView.OnChildClickListener{
15.
16. private List<PhoneGroup> groups;
17.
18. private PhoneGroupAdapter exlist_adapter = null;
19.
20. private ExpandableListView exlist;
21.
22. public void onCreate(Bundle savedInstanceState) {
23.
24. super.onCreate(savedInstanceState);
25.
26. //加载layout
27.
28. setContentView(R.layout.phone_browser);
29.
30. //取得listview
31.
32. exlist = (ExpandableListView) findViewById(R.id.phonelist);
33.
34. //调用init方法,这个方法主要是,初始化一些数据
35.
36. init();
37.
38. //构建expandablelistview的适配器
39.
40. exlist_adapter = new PhoneGroupAdapter(this, groups);
41.
42. exlist.setOnChildClickListener(this);
43.
44. exlist.setAdapter(exlist_adapter); //绑定视图-适配器
45.
46. }
47.
48. private void init() {
49.
50. groups = new ArrayList<PhoneGroup>();
51.
52.
53. //构建List用作group1的子项
54.
55. List<PhoneListItem> group1_children = new ArrayList<PhoneListItem>();
56.
57. //往List中添加内容
58.
59. PhoneListItem item = new PhoneListItem("和文明","1308763994", false);
60.
61. group1_children.add(item);
62.
63. item = new PhoneListItem("黄文明","1308763994", false);
64.
65. group1_children.add(item);
66.
67. item = new PhoneListItem("王文明","1308763994", false);
68.
69. group1_children.add(item);
70.
71. //拼装成 PhoneGroup
72.
73. PhoneGroup phonegroup1=new PhoneGroup("group1",false,group1_children);
74.
75. //------把前面的代码复制一遍,再添加一个组group2
76.
77. //构建List用作group2的子项
78.
79. List<PhoneListItem> group2_children = new ArrayList<PhoneListItem>();
80.
81. //往List中添加内容
82.
83. item = new PhoneListItem("张文明","1589065423", false);
84.
85. group2_children.add(item);
86.
87. item = new PhoneListItem("李文明","1589065423", false);
88.
89. group2_children.add(item);
90.
91. item = new PhoneListItem("赵文明","1589065423", false);
92.
93. group2_children.add(item);
94.
95. //拼装成 PhoneGroup
96.
97. PhoneGroup phonegroup2=new PhoneGroup("group2",false,group2_children);
98.
99. //添加进groups数组
100.
101. groups.add(phonegroup1);
102.
103. groups.add(phonegroup2);
104.
105. }
106.
107. //当分组行背点击时,让分组呈现“选中/取消选中”状态。
108.
109. @Override
110. public boolean onChildClick(ExpandableListView parent, View v,
111.
112. int groupPosition, int childPosition, long id) {
113.
114. PhoneGroupAdapter.ExpandableListHolder holder=(ExpandableListHolder) v.getTag();
115.
116. holder.chkChecked.setChecked(!holder.chkChecked.isChecked());
117.
118. groups.get(groupPosition).children.get(childPosition).checked=
119.
120. !groups.get(groupPosition).children.get(childPosition).checked;
121.
122. return false;
123.
124. }
125.
126. @Override
127. public boolean onGroupClick(ExpandableListView parent, View v,
128.
129. int groupPosition, long id) {
130.
131. // groups.get(groupPosition).setChecked(!groups.get(groupPosition).getChecked());
132.
133. // exlist_adapter.notifyDataSetChanged();
134.
135. return false;
136.
137. }
138.
139. }
复制代码
6、新建类PhoneGroupAdapter,实现BaseExpandableListAdapter。
Java代码:
1. package eoe.ydtf.android;
2.
3.
4. import java.util.List;
5. import android.content.Context;
6. import android.util.Log;
7. import android.view.LayoutInflater;
8. import android.view.View;
9. import android.view.View.OnClickListener;
10. import android.view.ViewGroup;
11. import android.widget.BaseExpandableListAdapter;
12. import android.widget.Button;
13. import android.widget.CheckBox;
14. import android.widget.CompoundButton;
15. import android.widget.CompoundButton.OnCheckedChangeListener;
16. import android.widget.TextView;
17.
18.
19. public class PhoneGroupAdapter extends BaseExpandableListAdapter {
20. class ExpandableListHolder { //定义一个内部类,用于保存listitem的3个子视图引用,2个textview和1个checkbox
21. TextView tvName;
22. TextView tvPhone;
23. CheckBox chkChecked;
24. }
25. private Context context; //父activity
26. private LayoutInflater mChildInflater; //用于加载listitem的布局xml
27. private LayoutInflater mGroupInflater; //用于加载group的布局xml
28. private List<PhoneGroup> groups; //所有group
29. //构造方法:参数c - activity,参数group - 所有group
30. public PhoneGroupAdapter(Context c,List<PhoneGroup> groups){
31. context=c;
32. mChildInflater = (LayoutInflater) context
33. .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
34. mGroupInflater = (LayoutInflater) context
35. .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
36. this.groups = groups;
37. }
38. @Override
39. public Object getChild(int arg0, int arg1) {//根据组索引和item索引,取得listitem // TODO Auto-generated method stub
40. return groups.get(arg0).children.get(arg1);
41. }
42. @Override
43. public long getChildId(int arg0, int arg1) {//返回item索引
44. return arg1;
45. }
46. @Override
47. public int getChildrenCount(int groupPosition) {//根据组索引返回分组的子item数
48. return groups.get(groupPosition).children.size();
49. }
50. @Override
51. public Object getGroup(int groupPosition) {//根据组索引返回组
52. return groups.get(groupPosition);
53. }
54. @Override
55. public int getGroupCount() {//返回分组数
56. return groups.size();
57. }
58. @Override
59. public long getGroupId(int groupPosition) {//返回分组索引
60. return groupPosition;
61. }
62. @Override
63. public View getGroupView(int position, boolean isExpanded,
64. View view, ViewGroup parent) {//根据组索引渲染"组视图"
65. ExpandableListHolder holder = null; //清空临时变量holder
66. if (view == null) { //判断view(即view是否已构建好)是否为空
67.
68. //若组视图为空,构建组视图。注意flate的使用,R.layout.browser_expandable_list_item代表了
69. //已加载到内存的browser_expandable_list_item.xml文件
70. view = mGroupInflater.inflate(
71. R.layout.phone_list_item, null);
72. //下面主要是取得组的各子视图,设置子视图的属性。用tag来保存各子视图的引用
73. holder = new ExpandableListHolder();
74. //从view中取得textView
75. holder.tvName = (TextView) view.findViewById(R.id.phone_name);
76. //从view中取得textview
77. holder.tvPhone = (TextView) view.findViewById(R.id.phone_number);
78. //从view中取得checkbox
79. holder.chkChecked = (CheckBox) view
80. .findViewById(R.id.phone_check);
81. // holder.chkChecked.setEnabled(false);//禁用checkbox
82. //把checkbox、textview的引用保存到组视图的tag属性中
83. view.setTag(holder);
84. } else { //若view不为空,直接从view的tag属性中获得各子视图的引用
85. holder = (ExpandableListHolder) view.getTag();
86. }
87. //对应于组索引的组数据(模型)
88. PhoneGroup info = this.groups.get(position);
89. if (info != null) {
90. //根据模型值设置textview的文本
91. holder.tvName.setText(info.title);
92. //根据模型值设置checkbox的checked属性
93. holder.chkChecked.setChecked(info.getChecked());
94. holder.chkChecked.setTag(info);
95. holder.chkChecked.setOnClickListener(new OnClickListener(){
96. @Override
97. public void onClick(View v) {
98. PhoneGroup group=(PhoneGroup)v.getTag();
99. group.setChecked(!group.getChecked());
100. notifyDataSetChanged();
101. }
102. });
103. }
104. // TODO Auto-generated method stub
105. return view;
106. }
107. //行渲染方法
108. @Override
109. public View getChildView(int groupPosition, int childPosition,
110. boolean isLastChild, View convertView, ViewGroup parent) {
111. ExpandableListHolder holder = null; //清空临时变量
112. if (convertView == null) { //若行未初始化
113. //通过flater初始化行视图
114. convertView = mChildInflater.inflate(
115. R.layout.phone_list_item, null);
116. //并将行视图的3个子视图引用放到tag中
117. holder = new ExpandableListHolder();
118. holder.tvName = (TextView) convertView
119. .findViewById(R.id.phone_name);
120.
121. holder.tvPhone = (TextView) convertView.findViewById(R.id.phone_number);
122. holder.chkChecked = (CheckBox) convertView
123. .findViewById(R.id.phone_check);
124. // holder.chkChecked.setEnabled(false);
125. convertView.setTag(holder);
126. } else { //若行已初始化,直接从tag属性获得子视图的引用
127. holder = (ExpandableListHolder) convertView.getTag();
128. }
129. //获得行数据(模型)
130. PhoneListItem info = this.groups.get(groupPosition)
131. .children.get(childPosition);
132.
133. if (info != null) {
134. //根据模型数据,设置行视图的控件值
135. holder.tvName.setText(info.name);
136. holder.tvPhone.setText(info.phone);
137. holder.chkChecked.setChecked(info.checked);
138. holder.chkChecked.setTag(info);
139. holder.chkChecked.setOnClickListener(new OnClickListener(){
140. @Override
141. public void onClick(View v) {
142. CheckBox check=(CheckBox)v;
143. PhoneListItem item=(PhoneListItem)v.getTag();
144. item.checked=!item.checked;
145. // check.setChecked(!check.isChecked());
146. }
147.
148. });
149. }
150. return convertView;
151. }
152. @Override
153. public boolean hasStableIds() {//行是否具有唯一id
154. return false;
155. }
156. @Override
157. public boolean isChildSelectable(int groupPosition, int childPosition) {//行是否可选
158. return true;
159. }
160. }