SimpleCursorTreeAdapter.java revision 54b6cfa9a9e5b861a9930af873580d6dc20f773c
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
17package android.widget;
18
19import android.content.Context;
20import android.database.Cursor;
21import android.net.Uri;
22import android.view.View;
23
24/**
25 * An easy adapter to map columns from a cursor to TextViews or ImageViews
26 * defined in an XML file. You can specify which columns you want, which views
27 * you want to display the columns, and the XML file that defines the appearance
28 * of these views. Separate XML files for child and groups are possible.
29 * TextViews bind the values to their text property (see
30 * {@link TextView#setText(CharSequence)}). ImageViews bind the values to their
31 * image's Uri property (see {@link ImageView#setImageURI(android.net.Uri)}).
32 */
33public abstract class SimpleCursorTreeAdapter extends ResourceCursorTreeAdapter {
34    /** The indices of columns that contain data to display for a group. */
35    private int[] mGroupFrom;
36    /**
37     * The View IDs that will display a group's data fetched from the
38     * corresponding column.
39     */
40    private int[] mGroupTo;
41
42    /** The indices of columns that contain data to display for a child. */
43    private int[] mChildFrom;
44    /**
45     * The View IDs that will display a child's data fetched from the
46     * corresponding column.
47     */
48    private int[] mChildTo;
49
50    /**
51     * Constructor.
52     *
53     * @param context The context where the {@link ExpandableListView}
54     *            associated with this {@link SimpleCursorTreeAdapter} is
55     *            running
56     * @param cursor The database cursor
57     * @param collapsedGroupLayout The resource identifier of a layout file that
58     *            defines the views for a collapsed group. The layout file
59     *            should include at least those named views defined in groupTo.
60     * @param expandedGroupLayout The resource identifier of a layout file that
61     *            defines the views for an expanded group. The layout file
62     *            should include at least those named views defined in groupTo.
63     * @param groupFrom A list of column names that will be used to display the
64     *            data for a group.
65     * @param groupTo The group views (from the group layouts) that should
66     *            display column in the "from" parameter. These should all be
67     *            TextViews or ImageViews. The first N views in this list are
68     *            given the values of the first N columns in the from parameter.
69     * @param childLayout The resource identifier of a layout file that defines
70     *            the views for a child (except the last). The layout file
71     *            should include at least those named views defined in childTo.
72     * @param lastChildLayout The resource identifier of a layout file that
73     *            defines the views for the last child within a group. The
74     *            layout file should include at least those named views defined
75     *            in childTo.
76     * @param childFrom A list of column names that will be used to display the
77     *            data for a child.
78     * @param childTo The child views (from the child layouts) that should
79     *            display column in the "from" parameter. These should all be
80     *            TextViews or ImageViews. The first N views in this list are
81     *            given the values of the first N columns in the from parameter.
82     */
83    public SimpleCursorTreeAdapter(Context context, Cursor cursor, int collapsedGroupLayout,
84            int expandedGroupLayout, String[] groupFrom, int[] groupTo, int childLayout,
85            int lastChildLayout, String[] childFrom, int[] childTo) {
86        super(context, cursor, collapsedGroupLayout, expandedGroupLayout, childLayout,
87                lastChildLayout);
88        init(groupFrom, groupTo, childFrom, childTo);
89    }
90
91    /**
92     * Constructor.
93     *
94     * @param context The context where the {@link ExpandableListView}
95     *            associated with this {@link SimpleCursorTreeAdapter} is
96     *            running
97     * @param cursor The database cursor
98     * @param collapsedGroupLayout The resource identifier of a layout file that
99     *            defines the views for a collapsed group. The layout file
100     *            should include at least those named views defined in groupTo.
101     * @param expandedGroupLayout The resource identifier of a layout file that
102     *            defines the views for an expanded group. The layout file
103     *            should include at least those named views defined in groupTo.
104     * @param groupFrom A list of column names that will be used to display the
105     *            data for a group.
106     * @param groupTo The group views (from the group layouts) that should
107     *            display column in the "from" parameter. These should all be
108     *            TextViews or ImageViews. The first N views in this list are
109     *            given the values of the first N columns in the from parameter.
110     * @param childLayout The resource identifier of a layout file that defines
111     *            the views for a child. The layout file
112     *            should include at least those named views defined in childTo.
113     * @param childFrom A list of column names that will be used to display the
114     *            data for a child.
115     * @param childTo The child views (from the child layouts) that should
116     *            display column in the "from" parameter. These should all be
117     *            TextViews or ImageViews. The first N views in this list are
118     *            given the values of the first N columns in the from parameter.
119     */
120    public SimpleCursorTreeAdapter(Context context, Cursor cursor, int collapsedGroupLayout,
121            int expandedGroupLayout, String[] groupFrom, int[] groupTo,
122            int childLayout, String[] childFrom, int[] childTo) {
123        super(context, cursor, collapsedGroupLayout, expandedGroupLayout, childLayout);
124        init(groupFrom, groupTo, childFrom, childTo);
125    }
126
127    /**
128     * Constructor.
129     *
130     * @param context The context where the {@link ExpandableListView}
131     *            associated with this {@link SimpleCursorTreeAdapter} is
132     *            running
133     * @param cursor The database cursor
134     * @param groupLayout The resource identifier of a layout file that defines
135     *            the views for a group. The layout file should include at least
136     *            those named views defined in groupTo.
137     * @param groupFrom A list of column names that will be used to display the
138     *            data for a group.
139     * @param groupTo The group views (from the group layouts) that should
140     *            display column in the "from" parameter. These should all be
141     *            TextViews or ImageViews. The first N views in this list are
142     *            given the values of the first N columns in the from parameter.
143     * @param childLayout The resource identifier of a layout file that defines
144     *            the views for a child. The layout file should include at least
145     *            those named views defined in childTo.
146     * @param childFrom A list of column names that will be used to display the
147     *            data for a child.
148     * @param childTo The child views (from the child layouts) that should
149     *            display column in the "from" parameter. These should all be
150     *            TextViews or ImageViews. The first N views in this list are
151     *            given the values of the first N columns in the from parameter.
152     */
153    public SimpleCursorTreeAdapter(Context context, Cursor cursor, int groupLayout,
154            String[] groupFrom, int[] groupTo, int childLayout, String[] childFrom,
155            int[] childTo) {
156        super(context, cursor, groupLayout, childLayout);
157        init(groupFrom, groupTo, childFrom, childTo);
158    }
159
160    private void init(String[] groupFromNames, int[] groupTo, String[] childFromNames,
161            int[] childTo) {
162        mGroupTo = groupTo;
163
164        mChildTo = childTo;
165
166        // Get the group cursor column indices, the child cursor column indices will come
167        // when needed
168        initGroupFromColumns(groupFromNames);
169
170        // Get a temporary child cursor to init the column indices
171        if (getGroupCount() > 0) {
172            MyCursorHelper tmpCursorHelper = getChildrenCursorHelper(0, true);
173            if (tmpCursorHelper != null) {
174                initChildrenFromColumns(childFromNames, tmpCursorHelper.getCursor());
175                deactivateChildrenCursorHelper(0);
176            }
177        }
178    }
179
180    private void initFromColumns(Cursor cursor, String[] fromColumnNames, int[] fromColumns) {
181        for (int i = fromColumnNames.length - 1; i >= 0; i--) {
182            fromColumns[i] = cursor.getColumnIndexOrThrow(fromColumnNames[i]);
183        }
184    }
185
186    private void initGroupFromColumns(String[] groupFromNames) {
187        mGroupFrom = new int[groupFromNames.length];
188        initFromColumns(mGroupCursorHelper.getCursor(), groupFromNames, mGroupFrom);
189    }
190
191    private void initChildrenFromColumns(String[] childFromNames, Cursor childCursor) {
192        mChildFrom = new int[childFromNames.length];
193        initFromColumns(childCursor, childFromNames, mChildFrom);
194    }
195
196    private void bindView(View view, Context context, Cursor cursor, int[] from, int[] to) {
197        for (int i = 0; i < to.length; i++) {
198            View v = view.findViewById(to[i]);
199            if (v != null) {
200                String text = cursor.getString(from[i]);
201                if (text == null) {
202                    text = "";
203                }
204                if (v instanceof TextView) {
205                    ((TextView) v).setText(text);
206                } else if (v instanceof ImageView) {
207                    setViewImage((ImageView) v, text);
208                } else {
209                    throw new IllegalStateException("SimpleCursorAdapter can bind values only to" +
210                            " TextView and ImageView!");
211                }
212            }
213        }
214    }
215
216    @Override
217    protected void bindChildView(View view, Context context, Cursor cursor, boolean isLastChild) {
218        bindView(view, context, cursor, mChildFrom, mChildTo);
219    }
220
221    @Override
222    protected void bindGroupView(View view, Context context, Cursor cursor, boolean isExpanded) {
223        bindView(view, context, cursor, mGroupFrom, mGroupTo);
224    }
225
226    /**
227     * Called by bindView() to set the image for an ImageView. By default, the
228     * value will be treated as a Uri. Intended to be overridden by Adapters
229     * that need to filter strings retrieved from the database.
230     *
231     * @param v ImageView to receive an image
232     * @param value the value retrieved from the cursor
233     */
234    protected void setViewImage(ImageView v, String value) {
235        try {
236            v.setImageResource(Integer.parseInt(value));
237        } catch (NumberFormatException nfe) {
238            v.setImageURI(Uri.parse(value));
239        }
240    }
241}
242