1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.widget;
18 
19 import android.content.Context;
20 import android.view.LayoutInflater;
21 import android.view.View;
22 import android.view.ViewGroup;
23 
24 import java.util.List;
25 import java.util.Map;
26 
27 /**
28  * An easy adapter to map static data to group and child views defined in an XML
29  * file. You can separately specify the data backing the group as a List of
30  * Maps. Each entry in the ArrayList corresponds to one group in the expandable
31  * list. The Maps contain the data for each row. You also specify an XML file
32  * that defines the views used to display a group, and a mapping from keys in
33  * the Map to specific views. This process is similar for a child, except it is
34  * one-level deeper so the data backing is specified as a List<List<Map>>,
35  * where the first List corresponds to the group of the child, the second List
36  * corresponds to the position of the child within the group, and finally the
37  * Map holds the data for that particular child.
38  */
39 public class SimpleExpandableListAdapter extends BaseExpandableListAdapter {
40     private List<? extends Map<String, ?>> mGroupData;
41     private int mExpandedGroupLayout;
42     private int mCollapsedGroupLayout;
43     private String[] mGroupFrom;
44     private int[] mGroupTo;
45 
46     private List<? extends List<? extends Map<String, ?>>> mChildData;
47     private int mChildLayout;
48     private int mLastChildLayout;
49     private String[] mChildFrom;
50     private int[] mChildTo;
51 
52     private LayoutInflater mInflater;
53 
54     /**
55      * Constructor
56      *
57      * @param context The context where the {@link ExpandableListView}
58      *            associated with this {@link SimpleExpandableListAdapter} is
59      *            running
60      * @param groupData A List of Maps. Each entry in the List corresponds to
61      *            one group in the list. The Maps contain the data for each
62      *            group, and should include all the entries specified in
63      *            "groupFrom"
64      * @param groupFrom A list of keys that will be fetched from the Map
65      *            associated with each group.
66      * @param groupTo The group views that should display column in the
67      *            "groupFrom" parameter. These should all be TextViews. The
68      *            first N views in this list are given the values of the first N
69      *            columns in the groupFrom parameter.
70      * @param groupLayout resource identifier of a view layout that defines the
71      *            views for a group. The layout file should include at least
72      *            those named views defined in "groupTo"
73      * @param childData A List of List of Maps. Each entry in the outer List
74      *            corresponds to a group (index by group position), each entry
75      *            in the inner List corresponds to a child within the group
76      *            (index by child position), and the Map corresponds to the data
77      *            for a child (index by values in the childFrom array). The Map
78      *            contains the data for each child, and should include all the
79      *            entries specified in "childFrom"
80      * @param childFrom A list of keys that will be fetched from the Map
81      *            associated with each child.
82      * @param childTo The child views that should display column in the
83      *            "childFrom" parameter. These should all be TextViews. The
84      *            first N views in this list are given the values of the first N
85      *            columns in the childFrom parameter.
86      * @param childLayout resource identifier of a view layout that defines the
87      *            views for a child. The layout file should include at least
88      *            those named views defined in "childTo"
89      */
SimpleExpandableListAdapter(Context context, List<? extends Map<String, ?>> groupData, int groupLayout, String[] groupFrom, int[] groupTo, List<? extends List<? extends Map<String, ?>>> childData, int childLayout, String[] childFrom, int[] childTo)90     public SimpleExpandableListAdapter(Context context,
91             List<? extends Map<String, ?>> groupData, int groupLayout,
92             String[] groupFrom, int[] groupTo,
93             List<? extends List<? extends Map<String, ?>>> childData,
94             int childLayout, String[] childFrom, int[] childTo) {
95         this(context, groupData, groupLayout, groupLayout, groupFrom, groupTo, childData,
96                 childLayout, childLayout, childFrom, childTo);
97     }
98 
99     /**
100      * Constructor
101      *
102      * @param context The context where the {@link ExpandableListView}
103      *            associated with this {@link SimpleExpandableListAdapter} is
104      *            running
105      * @param groupData A List of Maps. Each entry in the List corresponds to
106      *            one group in the list. The Maps contain the data for each
107      *            group, and should include all the entries specified in
108      *            "groupFrom"
109      * @param groupFrom A list of keys that will be fetched from the Map
110      *            associated with each group.
111      * @param groupTo The group views that should display column in the
112      *            "groupFrom" parameter. These should all be TextViews. The
113      *            first N views in this list are given the values of the first N
114      *            columns in the groupFrom parameter.
115      * @param expandedGroupLayout resource identifier of a view layout that
116      *            defines the views for an expanded group. The layout file
117      *            should include at least those named views defined in "groupTo"
118      * @param collapsedGroupLayout resource identifier of a view layout that
119      *            defines the views for a collapsed group. The layout file
120      *            should include at least those named views defined in "groupTo"
121      * @param childData A List of List of Maps. Each entry in the outer List
122      *            corresponds to a group (index by group position), each entry
123      *            in the inner List corresponds to a child within the group
124      *            (index by child position), and the Map corresponds to the data
125      *            for a child (index by values in the childFrom array). The Map
126      *            contains the data for each child, and should include all the
127      *            entries specified in "childFrom"
128      * @param childFrom A list of keys that will be fetched from the Map
129      *            associated with each child.
130      * @param childTo The child views that should display column in the
131      *            "childFrom" parameter. These should all be TextViews. The
132      *            first N views in this list are given the values of the first N
133      *            columns in the childFrom parameter.
134      * @param childLayout resource identifier of a view layout that defines the
135      *            views for a child. The layout file should include at least
136      *            those named views defined in "childTo"
137      */
SimpleExpandableListAdapter(Context context, List<? extends Map<String, ?>> groupData, int expandedGroupLayout, int collapsedGroupLayout, String[] groupFrom, int[] groupTo, List<? extends List<? extends Map<String, ?>>> childData, int childLayout, String[] childFrom, int[] childTo)138     public SimpleExpandableListAdapter(Context context,
139             List<? extends Map<String, ?>> groupData, int expandedGroupLayout,
140             int collapsedGroupLayout, String[] groupFrom, int[] groupTo,
141             List<? extends List<? extends Map<String, ?>>> childData,
142             int childLayout, String[] childFrom, int[] childTo) {
143         this(context, groupData, expandedGroupLayout, collapsedGroupLayout,
144                 groupFrom, groupTo, childData, childLayout, childLayout,
145                 childFrom, childTo);
146     }
147 
148     /**
149      * Constructor
150      *
151      * @param context The context where the {@link ExpandableListView}
152      *            associated with this {@link SimpleExpandableListAdapter} is
153      *            running
154      * @param groupData A List of Maps. Each entry in the List corresponds to
155      *            one group in the list. The Maps contain the data for each
156      *            group, and should include all the entries specified in
157      *            "groupFrom"
158      * @param groupFrom A list of keys that will be fetched from the Map
159      *            associated with each group.
160      * @param groupTo The group views that should display column in the
161      *            "groupFrom" parameter. These should all be TextViews. The
162      *            first N views in this list are given the values of the first N
163      *            columns in the groupFrom parameter.
164      * @param expandedGroupLayout resource identifier of a view layout that
165      *            defines the views for an expanded group. The layout file
166      *            should include at least those named views defined in "groupTo"
167      * @param collapsedGroupLayout resource identifier of a view layout that
168      *            defines the views for a collapsed group. The layout file
169      *            should include at least those named views defined in "groupTo"
170      * @param childData A List of List of Maps. Each entry in the outer List
171      *            corresponds to a group (index by group position), each entry
172      *            in the inner List corresponds to a child within the group
173      *            (index by child position), and the Map corresponds to the data
174      *            for a child (index by values in the childFrom array). The Map
175      *            contains the data for each child, and should include all the
176      *            entries specified in "childFrom"
177      * @param childFrom A list of keys that will be fetched from the Map
178      *            associated with each child.
179      * @param childTo The child views that should display column in the
180      *            "childFrom" parameter. These should all be TextViews. The
181      *            first N views in this list are given the values of the first N
182      *            columns in the childFrom parameter.
183      * @param childLayout resource identifier of a view layout that defines the
184      *            views for a child (unless it is the last child within a group,
185      *            in which case the lastChildLayout is used). The layout file
186      *            should include at least those named views defined in "childTo"
187      * @param lastChildLayout resource identifier of a view layout that defines
188      *            the views for the last child within each group. The layout
189      *            file should include at least those named views defined in
190      *            "childTo"
191      */
SimpleExpandableListAdapter(Context context, List<? extends Map<String, ?>> groupData, int expandedGroupLayout, int collapsedGroupLayout, String[] groupFrom, int[] groupTo, List<? extends List<? extends Map<String, ?>>> childData, int childLayout, int lastChildLayout, String[] childFrom, int[] childTo)192     public SimpleExpandableListAdapter(Context context,
193             List<? extends Map<String, ?>> groupData, int expandedGroupLayout,
194             int collapsedGroupLayout, String[] groupFrom, int[] groupTo,
195             List<? extends List<? extends Map<String, ?>>> childData,
196             int childLayout, int lastChildLayout, String[] childFrom,
197             int[] childTo) {
198         mGroupData = groupData;
199         mExpandedGroupLayout = expandedGroupLayout;
200         mCollapsedGroupLayout = collapsedGroupLayout;
201         mGroupFrom = groupFrom;
202         mGroupTo = groupTo;
203 
204         mChildData = childData;
205         mChildLayout = childLayout;
206         mLastChildLayout = lastChildLayout;
207         mChildFrom = childFrom;
208         mChildTo = childTo;
209 
210         mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
211     }
212 
getChild(int groupPosition, int childPosition)213     public Object getChild(int groupPosition, int childPosition) {
214         return mChildData.get(groupPosition).get(childPosition);
215     }
216 
getChildId(int groupPosition, int childPosition)217     public long getChildId(int groupPosition, int childPosition) {
218         return childPosition;
219     }
220 
getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent)221     public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
222             View convertView, ViewGroup parent) {
223         View v;
224         if (convertView == null) {
225             v = newChildView(isLastChild, parent);
226         } else {
227             v = convertView;
228         }
229         bindView(v, mChildData.get(groupPosition).get(childPosition), mChildFrom, mChildTo);
230         return v;
231     }
232 
233     /**
234      * Instantiates a new View for a child.
235      * @param isLastChild Whether the child is the last child within its group.
236      * @param parent The eventual parent of this new View.
237      * @return A new child View
238      */
newChildView(boolean isLastChild, ViewGroup parent)239     public View newChildView(boolean isLastChild, ViewGroup parent) {
240         return mInflater.inflate((isLastChild) ? mLastChildLayout : mChildLayout, parent, false);
241     }
242 
bindView(View view, Map<String, ?> data, String[] from, int[] to)243     private void bindView(View view, Map<String, ?> data, String[] from, int[] to) {
244         int len = to.length;
245 
246         for (int i = 0; i < len; i++) {
247             TextView v = (TextView)view.findViewById(to[i]);
248             if (v != null) {
249                 v.setText((String)data.get(from[i]));
250             }
251         }
252     }
253 
getChildrenCount(int groupPosition)254     public int getChildrenCount(int groupPosition) {
255         return mChildData.get(groupPosition).size();
256     }
257 
getGroup(int groupPosition)258     public Object getGroup(int groupPosition) {
259         return mGroupData.get(groupPosition);
260     }
261 
getGroupCount()262     public int getGroupCount() {
263         return mGroupData.size();
264     }
265 
getGroupId(int groupPosition)266     public long getGroupId(int groupPosition) {
267         return groupPosition;
268     }
269 
getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent)270     public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
271             ViewGroup parent) {
272         View v;
273         if (convertView == null) {
274             v = newGroupView(isExpanded, parent);
275         } else {
276             v = convertView;
277         }
278         bindView(v, mGroupData.get(groupPosition), mGroupFrom, mGroupTo);
279         return v;
280     }
281 
282     /**
283      * Instantiates a new View for a group.
284      * @param isExpanded Whether the group is currently expanded.
285      * @param parent The eventual parent of this new View.
286      * @return A new group View
287      */
newGroupView(boolean isExpanded, ViewGroup parent)288     public View newGroupView(boolean isExpanded, ViewGroup parent) {
289         return mInflater.inflate((isExpanded) ? mExpandedGroupLayout : mCollapsedGroupLayout,
290                 parent, false);
291     }
292 
isChildSelectable(int groupPosition, int childPosition)293     public boolean isChildSelectable(int groupPosition, int childPosition) {
294         return true;
295     }
296 
hasStableIds()297     public boolean hasStableIds() {
298         return true;
299     }
300 
301 }
302