/* * Copyright (C) 2006 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.widget; import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.view.LayoutInflater; import java.util.List; import java.util.Map; /** * An easy adapter to map static data to group and child views defined in an XML * file. You can separately specify the data backing the group as a List of * Maps. Each entry in the ArrayList corresponds to one group in the expandable * list. The Maps contain the data for each row. You also specify an XML file * that defines the views used to display a group, and a mapping from keys in * the Map to specific views. This process is similar for a child, except it is * one-level deeper so the data backing is specified as a List>, * where the first List corresponds to the group of the child, the second List * corresponds to the position of the child within the group, and finally the * Map holds the data for that particular child. */ public class SimpleExpandableListAdapter extends BaseExpandableListAdapter { private List> mGroupData; private int mExpandedGroupLayout; private int mCollapsedGroupLayout; private String[] mGroupFrom; private int[] mGroupTo; private List>> mChildData; private int mChildLayout; private int mLastChildLayout; private String[] mChildFrom; private int[] mChildTo; private LayoutInflater mInflater; /** * Constructor * * @param context The context where the {@link ExpandableListView} * associated with this {@link SimpleExpandableListAdapter} is * running * @param groupData A List of Maps. Each entry in the List corresponds to * one group in the list. The Maps contain the data for each * group, and should include all the entries specified in * "groupFrom" * @param groupFrom A list of keys that will be fetched from the Map * associated with each group. * @param groupTo The group views that should display column in the * "groupFrom" parameter. These should all be TextViews. The * first N views in this list are given the values of the first N * columns in the groupFrom parameter. * @param groupLayout resource identifier of a view layout that defines the * views for a group. The layout file should include at least * those named views defined in "groupTo" * @param childData A List of List of Maps. Each entry in the outer List * corresponds to a group (index by group position), each entry * in the inner List corresponds to a child within the group * (index by child position), and the Map corresponds to the data * for a child (index by values in the childFrom array). The Map * contains the data for each child, and should include all the * entries specified in "childFrom" * @param childFrom A list of keys that will be fetched from the Map * associated with each child. * @param childTo The child views that should display column in the * "childFrom" parameter. These should all be TextViews. The * first N views in this list are given the values of the first N * columns in the childFrom parameter. * @param childLayout resource identifier of a view layout that defines the * views for a child. The layout file should include at least * those named views defined in "childTo" */ public SimpleExpandableListAdapter(Context context, List> groupData, int groupLayout, String[] groupFrom, int[] groupTo, List>> childData, int childLayout, String[] childFrom, int[] childTo) { this(context, groupData, groupLayout, groupLayout, groupFrom, groupTo, childData, childLayout, childLayout, childFrom, childTo); } /** * Constructor * * @param context The context where the {@link ExpandableListView} * associated with this {@link SimpleExpandableListAdapter} is * running * @param groupData A List of Maps. Each entry in the List corresponds to * one group in the list. The Maps contain the data for each * group, and should include all the entries specified in * "groupFrom" * @param groupFrom A list of keys that will be fetched from the Map * associated with each group. * @param groupTo The group views that should display column in the * "groupFrom" parameter. These should all be TextViews. The * first N views in this list are given the values of the first N * columns in the groupFrom parameter. * @param expandedGroupLayout resource identifier of a view layout that * defines the views for an expanded group. The layout file * should include at least those named views defined in "groupTo" * @param collapsedGroupLayout resource identifier of a view layout that * defines the views for a collapsed group. The layout file * should include at least those named views defined in "groupTo" * @param childData A List of List of Maps. Each entry in the outer List * corresponds to a group (index by group position), each entry * in the inner List corresponds to a child within the group * (index by child position), and the Map corresponds to the data * for a child (index by values in the childFrom array). The Map * contains the data for each child, and should include all the * entries specified in "childFrom" * @param childFrom A list of keys that will be fetched from the Map * associated with each child. * @param childTo The child views that should display column in the * "childFrom" parameter. These should all be TextViews. The * first N views in this list are given the values of the first N * columns in the childFrom parameter. * @param childLayout resource identifier of a view layout that defines the * views for a child. The layout file should include at least * those named views defined in "childTo" */ public SimpleExpandableListAdapter(Context context, List> groupData, int expandedGroupLayout, int collapsedGroupLayout, String[] groupFrom, int[] groupTo, List>> childData, int childLayout, String[] childFrom, int[] childTo) { this(context, groupData, expandedGroupLayout, collapsedGroupLayout, groupFrom, groupTo, childData, childLayout, childLayout, childFrom, childTo); } /** * Constructor * * @param context The context where the {@link ExpandableListView} * associated with this {@link SimpleExpandableListAdapter} is * running * @param groupData A List of Maps. Each entry in the List corresponds to * one group in the list. The Maps contain the data for each * group, and should include all the entries specified in * "groupFrom" * @param groupFrom A list of keys that will be fetched from the Map * associated with each group. * @param groupTo The group views that should display column in the * "groupFrom" parameter. These should all be TextViews. The * first N views in this list are given the values of the first N * columns in the groupFrom parameter. * @param expandedGroupLayout resource identifier of a view layout that * defines the views for an expanded group. The layout file * should include at least those named views defined in "groupTo" * @param collapsedGroupLayout resource identifier of a view layout that * defines the views for a collapsed group. The layout file * should include at least those named views defined in "groupTo" * @param childData A List of List of Maps. Each entry in the outer List * corresponds to a group (index by group position), each entry * in the inner List corresponds to a child within the group * (index by child position), and the Map corresponds to the data * for a child (index by values in the childFrom array). The Map * contains the data for each child, and should include all the * entries specified in "childFrom" * @param childFrom A list of keys that will be fetched from the Map * associated with each child. * @param childTo The child views that should display column in the * "childFrom" parameter. These should all be TextViews. The * first N views in this list are given the values of the first N * columns in the childFrom parameter. * @param childLayout resource identifier of a view layout that defines the * views for a child (unless it is the last child within a group, * in which case the lastChildLayout is used). The layout file * should include at least those named views defined in "childTo" * @param lastChildLayout resource identifier of a view layout that defines * the views for the last child within each group. The layout * file should include at least those named views defined in * "childTo" */ public SimpleExpandableListAdapter(Context context, List> groupData, int expandedGroupLayout, int collapsedGroupLayout, String[] groupFrom, int[] groupTo, List>> childData, int childLayout, int lastChildLayout, String[] childFrom, int[] childTo) { mGroupData = groupData; mExpandedGroupLayout = expandedGroupLayout; mCollapsedGroupLayout = collapsedGroupLayout; mGroupFrom = groupFrom; mGroupTo = groupTo; mChildData = childData; mChildLayout = childLayout; mLastChildLayout = lastChildLayout; mChildFrom = childFrom; mChildTo = childTo; mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } public Object getChild(int groupPosition, int childPosition) { return mChildData.get(groupPosition).get(childPosition); } public long getChildId(int groupPosition, int childPosition) { return childPosition; } public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { View v; if (convertView == null) { v = newChildView(isLastChild, parent); } else { v = convertView; } bindView(v, mChildData.get(groupPosition).get(childPosition), mChildFrom, mChildTo); return v; } /** * Instantiates a new View for a child. * @param isLastChild Whether the child is the last child within its group. * @param parent The eventual parent of this new View. * @return A new child View */ public View newChildView(boolean isLastChild, ViewGroup parent) { return mInflater.inflate((isLastChild) ? mLastChildLayout : mChildLayout, parent, false); } private void bindView(View view, Map data, String[] from, int[] to) { int len = to.length; for (int i = 0; i < len; i++) { TextView v = (TextView)view.findViewById(to[i]); if (v != null) { v.setText((String)data.get(from[i])); } } } public int getChildrenCount(int groupPosition) { return mChildData.get(groupPosition).size(); } public Object getGroup(int groupPosition) { return mGroupData.get(groupPosition); } public int getGroupCount() { return mGroupData.size(); } public long getGroupId(int groupPosition) { return groupPosition; } public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { View v; if (convertView == null) { v = newGroupView(isExpanded, parent); } else { v = convertView; } bindView(v, mGroupData.get(groupPosition), mGroupFrom, mGroupTo); return v; } /** * Instantiates a new View for a group. * @param isExpanded Whether the group is currently expanded. * @param parent The eventual parent of this new View. * @return A new group View */ public View newGroupView(boolean isExpanded, ViewGroup parent) { return mInflater.inflate((isExpanded) ? mExpandedGroupLayout : mCollapsedGroupLayout, parent, false); } public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } public boolean hasStableIds() { return true; } }