`

Android 自訂的 ExpandableList 加上 CheckBox

 
阅读更多

ExpandableList 跟 ListView 的實作觀念一樣
可以用 SimpleExpandableListAdapter 跟繼承 BaseExpandableListAdapter 的自訂 Adapter
由於 ExpandableList 有二層的資料
所以在 Adapter 要分別設定 Group 與 Child 的資料
實作是比較複雜一點

 

如果要在 ExpandableList 的 Group 及 Child 分別加上 CheckBox
而且 Group 的 CheckBox 跟 Child 的 CheckBox 互相關聯的話
在自訂 Adapter 就必須注意幾點

  1. 在 getGroupView 函式必須設定 CheckBox 監聽 Click 事件,並且綁定實作自訂的 Click 事件
  2. 在自訂的 Click 事件裡,改變原始資料後,呼叫 notifyDataSetChanged 函式,通知 ExpandableList 重新產生畫面

 

activity_main.xml

1
2
3
4
5
<ExpandableListView
    android:id="@+id/listView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >
</ExpandableListView>

group_layout.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<TextView
    android:id="@+id/tvGroup"
    android:layout_width="280dp"
    android:layout_height="45dip"
    android:gravity="center_vertical|left"
    android:paddingLeft="45dp"
    android:textSize="17dip"
    android:textStyle="bold" >
</TextView>
 
 
<CheckBox
    android:id="@+id/chbGroup"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:focusable="false" />

group_layout.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<TextView
    android:id="@+id/tvChild"
    android:layout_width="280dp"
    android:layout_height="45dip"
    android:gravity="center_vertical"
    android:paddingLeft="45dp"
    android:textSize="17dip"
    android:textStyle="bold" >
</TextView>
 
<CheckBox
    android:id="@+id/chbChild"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:focusable="false" />

MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
 
    groups = new ArrayList<Group>();
    getJSONObject();
    listView = (ExpandableListView) findViewById(R.id.listView);
    adapter = new EListAdapter(this, groups);
    listView.setAdapter(adapter);
}
 
/** 解悉 JSON 字串 */
private void getJSONObject() {
    String jsonStr = "{'CommunityUsersResult':[{'CommunityUsersList':[{'fullname':'a111','userid':11,'username':'a1'}"
            + ",{'fullname':'b222','userid':12,'username':'b2'}],'id':1,'title':'人事部'},{'CommunityUsersList':[{'fullname':"
            + "'c333','userid':13,'username':'c3'},{'fullname':'d444','userid':14,'username':'d4'},{'fullname':'e555','userid':"
            + "15,'username':'e5'}],'id':2,'title':'開發部'},{'CommunityUsersList':[],'id':3,'title':'業務部'}]}";
 
    try {
        JSONObject CommunityUsersResultObj = new JSONObject(jsonStr);
        JSONArray groupList = CommunityUsersResultObj.getJSONArray("CommunityUsersResult");
 
        for (int i = 0; i < groupList.length(); i++) {
            JSONObject groupObj = (JSONObject) groupList.get(i);
            Group group = new Group(groupObj.getString("id"), groupObj.getString("title"));
            JSONArray childrenList = groupObj.getJSONArray("CommunityUsersList");
 
            for (int j = 0; j < childrenList.length(); j++) {
                JSONObject childObj = (JSONObject) childrenList.get(j);
                Child child = new Child(childObj.getString("userid"), childObj.getString("fullname"), childObj.getString("username"));
                group.addChildrenItem(child);
            }
 
            groups.add(group);
        }
    } catch (JSONException e) {
        Log.d("allenj", e.toString());
    }
}

EListAdapter.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
public class EListAdapter extends BaseExpandableListAdapter {
 
    private Context context;
    private ArrayList<Group> groups;
 
    public EListAdapter(Context context, ArrayList<Group> groups) {
        this.context = context;
        this.groups = groups;
    }
 
    public Object getChild(int groupPosition, int childPosition) {
        groups.get(groupPosition).getChildItem(childPosition);
        return null;
    }
 
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }
 
    public int getChildrenCount(int groupPosition) {
        return groups.get(groupPosition).getChildrenCount();
    }
 
    public Object getGroup(int groupPosition) {
        return groups.get(groupPosition);
    }
 
    public int getGroupCount() {
        return groups.size();
    }
 
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }
 
    public boolean hasStableIds() {
        return false;
    }
 
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return false;
    }
 
    /** 設定 Group 資料 */
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
 
        Group group = (Group) getGroup(groupPosition);
 
        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.group_layout, null);
        }
 
        TextView tv = (TextView) convertView.findViewById(R.id.tvGroup);
        tv.setText(group.getTitle());
 
        // 重新產生 CheckBox 時,將存起來的 isChecked 狀態重新設定
        CheckBox checkBox = (CheckBox) convertView.findViewById(R.id.chbGroup);
        checkBox.setChecked(group.getChecked());
 
        // 點擊 CheckBox 時,將狀態存起來
        checkBox.setOnClickListener(new Group_CheckBox_Click(Integer.valueOf(groupPosition)));
 
        return convertView;
    }
 
    /** 勾選 Group CheckBox 時,存 Group CheckBox 的狀態,以及改變 Child CheckBox 的狀態 */
    class Group_CheckBox_Click implements OnClickListener {
        private int groupPosition;
 
        Group_CheckBox_Click(int groupPosition) {
            this.groupPosition = groupPosition;
        }
 
        public void onClick(View v) {
            groups.get(groupPosition).toggle();
 
            // 將 Children 的 isChecked 全面設成跟 Group 一樣
            int childrenCount = groups.get(groupPosition).getChildrenCount();
            boolean groupIsChecked = groups.get(groupPosition).getChecked();
            for (int i = 0; i < childrenCount; i++)
                groups.get(groupPosition).getChildItem(i).setChecked(groupIsChecked);
 
            // 注意,一定要通知 ExpandableListView 資料已經改變,ExpandableListView 會重新產生畫面
            notifyDataSetChanged();
        }
    }
 
    /** 設定 Children 資料 */
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
 
        Child child = groups.get(groupPosition).getChildItem(childPosition);
 
        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.child_layout, null);
        }
 
        TextView tv = (TextView) convertView.findViewById(R.id.tvChild);
        tv.setText(child.getFullname());
 
        // 重新產生 CheckBox 時,將存起來的 isChecked 狀態重新設定
        CheckBox checkBox = (CheckBox) convertView.findViewById(R.id.chbChild);
        checkBox.setChecked(child.getChecked());
 
        // 點擊 CheckBox 時,將狀態存起來
        checkBox.setOnClickListener(new Child_CheckBox_Click(Integer.valueOf(groupPosition), Integer.valueOf(childPosition)));
 
        return convertView;
    }
 
    /** 勾選 Child CheckBox 時,存 Child CheckBox 的狀態 */
    class Child_CheckBox_Click implements OnClickListener {
        private int groupPosition;
        private int childPosition;
 
        Child_CheckBox_Click(int groupPosition, int childPosition) {
            this.groupPosition = groupPosition;
            this.childPosition = childPosition;
        }
 
        public void onClick(View v) {
            groups.get(groupPosition).getChildItem(childPosition).toggle();
 
            // 檢查 Child CheckBox 是否有全部勾選,以控制 Group CheckBox
            int childrenCount = groups.get(groupPosition).getChildrenCount();
            boolean childrenAllIsChecked = true;
            for (int i = 0; i < childrenCount; i++) {
                if (!groups.get(groupPosition).getChildItem(i).getChecked())
                    childrenAllIsChecked = false;
            }
 
            groups.get(groupPosition).setChecked(childrenAllIsChecked);
 
            // 注意,一定要通知 ExpandableListView 資料已經改變,ExpandableListView 會重新產生畫面
            notifyDataSetChanged();
        }
    }
}

Group.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class Group {
    private String id;
    private String title;
    private ArrayList<Child> children;
    private boolean isChecked;
 
    public Group(String id, String title) {
        this.id = id;
        this.title = title;
        children = new ArrayList<Child>();
        this.isChecked = false;
    }
 
    public void setChecked(boolean isChecked) {
        this.isChecked = isChecked;
    }
 
    public void toggle() {
        this.isChecked = !this.isChecked;
    }
 
    public boolean getChecked() {
        return this.isChecked;
    }
 
    public String getId() {
        return id;
    }
 
    public String getTitle() {
        return title;
    }
 
    public void addChildrenItem(Child child) {
        children.add(child);
    }
 
    public int getChildrenCount() {
        return children.size();
    }
 
    public Child getChildItem(int index) {
        return children.get(index);
    }
}

Group.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class Child {
    private String userid;
    private String fullname;
    private String username;
    private boolean isChecked;
 
    public Child(String userid, String fullname, String username) {
        this.userid = userid;
        this.fullname = fullname;
        this.username = username;
        this.isChecked = false;
    }
 
    public void setChecked(boolean isChecked) {
        this.isChecked = isChecked;
    }
 
    public void toggle() {
        this.isChecked = !this.isChecked;
    }
 
    public boolean getChecked() {
        return this.isChecked;
    }
 
    public String getUserid() {
        return userid;
    }
 
    public String getFullname() {
        return fullname;
    }
 
    public String getUsername() {
        return username;
    }
}

 

注意事項
SimpleExpandableListAdapter 呼叫 notifyDataSetChanged 函式時
是在 New 出一個 Adapter 時,用 adapter.notifyDataSetChanged()
不過自訂 Adapter 的話,要在自訂 Adapter 類別裡呼叫 notifyDataSetChanged() 即可
這一點筆者也是卡了很久

转载:http://www.allenj.net/?p=3644
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics