switch to alsa.omap3 module
[android_pandora.git] / apps / AndroidSupportV2 / src / android / support / v2 / widget / SimpleCursorAdapter.java
CommitLineData
811a5a4a 1/*
2 * Copyright (C) 2011 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.support.v2.widget;
18
19import android.content.Context;
20import android.database.Cursor;
21import android.net.Uri;
22import android.view.View;
23import android.widget.ImageView;
24import android.widget.TextView;
25
26/**
27 * Static library support version of the framework's {@link android.widget.SimpleCursorAdapter}.
28 * Used to write apps that run on platforms prior to Android 3.0. When running
29 * on Android 3.0 or above, this implementation is still used; it does not try
30 * to switch to the framework's implementation. See the framework SDK
31 * documentation for a class overview.
32 */
33public class SimpleCursorAdapter extends ResourceCursorAdapter {
34 /**
35 * A list of columns containing the data to bind to the UI.
36 * This field should be made private, so it is hidden from the SDK.
37 * {@hide}
38 */
39 protected int[] mFrom;
40 /**
41 * A list of View ids representing the views to which the data must be bound.
42 * This field should be made private, so it is hidden from the SDK.
43 * {@hide}
44 */
45 protected int[] mTo;
46
47 private int mStringConversionColumn = -1;
48 private CursorToStringConverter mCursorToStringConverter;
49 private ViewBinder mViewBinder;
50
51 String[] mOriginalFrom;
52
53 /**
54 * Constructor the enables auto-requery.
55 *
56 * @deprecated This option is discouraged, as it results in Cursor queries
57 * being performed on the application's UI thread and thus can cause poor
58 * responsiveness or even Application Not Responding errors. As an alternative,
59 * use {@link android.app.LoaderManager} with a {@link android.content.CursorLoader}.
60 */
61 @Deprecated
62 public SimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
63 super(context, layout, c);
64 mTo = to;
65 mOriginalFrom = from;
66 findColumns(from);
67 }
68
69 /**
70 * Standard constructor.
71 *
72 * @param context The context where the ListView associated with this
73 * SimpleListItemFactory is running
74 * @param layout resource identifier of a layout file that defines the views
75 * for this list item. The layout file should include at least
76 * those named views defined in "to"
77 * @param c The database cursor. Can be null if the cursor is not available yet.
78 * @param from A list of column names representing the data to bind to the UI. Can be null
79 * if the cursor is not available yet.
80 * @param to The views that should display column in the "from" parameter.
81 * These should all be TextViews. The first N views in this list
82 * are given the values of the first N columns in the from
83 * parameter. Can be null if the cursor is not available yet.
84 * @param flags Flags used to determine the behavior of the adapter,
85 * as per {@link CursorAdapter#CursorAdapter(Context, Cursor, int)}.
86 */
87 public SimpleCursorAdapter(Context context, int layout, Cursor c, String[] from,
88 int[] to, int flags) {
89 super(context, layout, c, flags);
90 mTo = to;
91 mOriginalFrom = from;
92 findColumns(from);
93 }
94
95 /**
96 * Binds all of the field names passed into the "to" parameter of the
97 * constructor with their corresponding cursor columns as specified in the
98 * "from" parameter.
99 *
100 * Binding occurs in two phases. First, if a
101 * {@link android.widget.SimpleCursorAdapter.ViewBinder} is available,
102 * {@link ViewBinder#setViewValue(android.view.View, android.database.Cursor, int)}
103 * is invoked. If the returned value is true, binding has occured. If the
104 * returned value is false and the view to bind is a TextView,
105 * {@link #setViewText(TextView, String)} is invoked. If the returned value is
106 * false and the view to bind is an ImageView,
107 * {@link #setViewImage(ImageView, String)} is invoked. If no appropriate
108 * binding can be found, an {@link IllegalStateException} is thrown.
109 *
110 * @throws IllegalStateException if binding cannot occur
111 *
112 * @see android.widget.CursorAdapter#bindView(android.view.View,
113 * android.content.Context, android.database.Cursor)
114 * @see #getViewBinder()
115 * @see #setViewBinder(android.widget.SimpleCursorAdapter.ViewBinder)
116 * @see #setViewImage(ImageView, String)
117 * @see #setViewText(TextView, String)
118 */
119 @Override
120 public void bindView(View view, Context context, Cursor cursor) {
121 final ViewBinder binder = mViewBinder;
122 final int count = mTo.length;
123 final int[] from = mFrom;
124 final int[] to = mTo;
125
126 for (int i = 0; i < count; i++) {
127 final View v = view.findViewById(to[i]);
128 if (v != null) {
129 boolean bound = false;
130 if (binder != null) {
131 bound = binder.setViewValue(v, cursor, from[i]);
132 }
133
134 if (!bound) {
135 String text = cursor.getString(from[i]);
136 if (text == null) {
137 text = "";
138 }
139
140 if (v instanceof TextView) {
141 setViewText((TextView) v, text);
142 } else if (v instanceof ImageView) {
143 setViewImage((ImageView) v, text);
144 } else {
145 throw new IllegalStateException(v.getClass().getName() + " is not a " +
146 " view that can be bounds by this SimpleCursorAdapter");
147 }
148 }
149 }
150 }
151 }
152
153 /**
154 * Returns the {@link ViewBinder} used to bind data to views.
155 *
156 * @return a ViewBinder or null if the binder does not exist
157 *
158 * @see #bindView(android.view.View, android.content.Context, android.database.Cursor)
159 * @see #setViewBinder(android.widget.SimpleCursorAdapter.ViewBinder)
160 */
161 public ViewBinder getViewBinder() {
162 return mViewBinder;
163 }
164
165 /**
166 * Sets the binder used to bind data to views.
167 *
168 * @param viewBinder the binder used to bind data to views, can be null to
169 * remove the existing binder
170 *
171 * @see #bindView(android.view.View, android.content.Context, android.database.Cursor)
172 * @see #getViewBinder()
173 */
174 public void setViewBinder(ViewBinder viewBinder) {
175 mViewBinder = viewBinder;
176 }
177
178 /**
179 * Called by bindView() to set the image for an ImageView but only if
180 * there is no existing ViewBinder or if the existing ViewBinder cannot
181 * handle binding to an ImageView.
182 *
183 * By default, the value will be treated as an image resource. If the
184 * value cannot be used as an image resource, the value is used as an
185 * image Uri.
186 *
187 * Intended to be overridden by Adapters that need to filter strings
188 * retrieved from the database.
189 *
190 * @param v ImageView to receive an image
191 * @param value the value retrieved from the cursor
192 */
193 public void setViewImage(ImageView v, String value) {
194 try {
195 v.setImageResource(Integer.parseInt(value));
196 } catch (NumberFormatException nfe) {
197 v.setImageURI(Uri.parse(value));
198 }
199 }
200
201 /**
202 * Called by bindView() to set the text for a TextView but only if
203 * there is no existing ViewBinder or if the existing ViewBinder cannot
204 * handle binding to an TextView.
205 *
206 * Intended to be overridden by Adapters that need to filter strings
207 * retrieved from the database.
208 *
209 * @param v TextView to receive text
210 * @param text the text to be set for the TextView
211 */
212 public void setViewText(TextView v, String text) {
213 v.setText(text);
214 }
215
216 /**
217 * Return the index of the column used to get a String representation
218 * of the Cursor.
219 *
220 * @return a valid index in the current Cursor or -1
221 *
222 * @see android.widget.CursorAdapter#convertToString(android.database.Cursor)
223 * @see #setStringConversionColumn(int)
224 * @see #setCursorToStringConverter(android.widget.SimpleCursorAdapter.CursorToStringConverter)
225 * @see #getCursorToStringConverter()
226 */
227 public int getStringConversionColumn() {
228 return mStringConversionColumn;
229 }
230
231 /**
232 * Defines the index of the column in the Cursor used to get a String
233 * representation of that Cursor. The column is used to convert the
234 * Cursor to a String only when the current CursorToStringConverter
235 * is null.
236 *
237 * @param stringConversionColumn a valid index in the current Cursor or -1 to use the default
238 * conversion mechanism
239 *
240 * @see android.widget.CursorAdapter#convertToString(android.database.Cursor)
241 * @see #getStringConversionColumn()
242 * @see #setCursorToStringConverter(android.widget.SimpleCursorAdapter.CursorToStringConverter)
243 * @see #getCursorToStringConverter()
244 */
245 public void setStringConversionColumn(int stringConversionColumn) {
246 mStringConversionColumn = stringConversionColumn;
247 }
248
249 /**
250 * Returns the converter used to convert the filtering Cursor
251 * into a String.
252 *
253 * @return null if the converter does not exist or an instance of
254 * {@link android.widget.SimpleCursorAdapter.CursorToStringConverter}
255 *
256 * @see #setCursorToStringConverter(android.widget.SimpleCursorAdapter.CursorToStringConverter)
257 * @see #getStringConversionColumn()
258 * @see #setStringConversionColumn(int)
259 * @see android.widget.CursorAdapter#convertToString(android.database.Cursor)
260 */
261 public CursorToStringConverter getCursorToStringConverter() {
262 return mCursorToStringConverter;
263 }
264
265 /**
266 * Sets the converter used to convert the filtering Cursor
267 * into a String.
268 *
269 * @param cursorToStringConverter the Cursor to String converter, or
270 * null to remove the converter
271 *
272 * @see #setCursorToStringConverter(android.widget.SimpleCursorAdapter.CursorToStringConverter)
273 * @see #getStringConversionColumn()
274 * @see #setStringConversionColumn(int)
275 * @see android.widget.CursorAdapter#convertToString(android.database.Cursor)
276 */
277 public void setCursorToStringConverter(CursorToStringConverter cursorToStringConverter) {
278 mCursorToStringConverter = cursorToStringConverter;
279 }
280
281 /**
282 * Returns a CharSequence representation of the specified Cursor as defined
283 * by the current CursorToStringConverter. If no CursorToStringConverter
284 * has been set, the String conversion column is used instead. If the
285 * conversion column is -1, the returned String is empty if the cursor
286 * is null or Cursor.toString().
287 *
288 * @param cursor the Cursor to convert to a CharSequence
289 *
290 * @return a non-null CharSequence representing the cursor
291 */
292 @Override
293 public CharSequence convertToString(Cursor cursor) {
294 if (mCursorToStringConverter != null) {
295 return mCursorToStringConverter.convertToString(cursor);
296 } else if (mStringConversionColumn > -1) {
297 return cursor.getString(mStringConversionColumn);
298 }
299
300 return super.convertToString(cursor);
301 }
302
303 /**
304 * Create a map from an array of strings to an array of column-id integers in mCursor.
305 * If mCursor is null, the array will be discarded.
306 *
307 * @param from the Strings naming the columns of interest
308 */
309 private void findColumns(String[] from) {
310 if (mCursor != null) {
311 int i;
312 int count = from.length;
313 if (mFrom == null || mFrom.length != count) {
314 mFrom = new int[count];
315 }
316 for (i = 0; i < count; i++) {
317 mFrom[i] = mCursor.getColumnIndexOrThrow(from[i]);
318 }
319 } else {
320 mFrom = null;
321 }
322 }
323
324 @Override
325 public Cursor swapCursor(Cursor c) {
326 Cursor res = super.swapCursor(c);
327 // rescan columns in case cursor layout is different
328 findColumns(mOriginalFrom);
329 return res;
330 }
331
332 /**
333 * Change the cursor and change the column-to-view mappings at the same time.
334 *
335 * @param c The database cursor. Can be null if the cursor is not available yet.
336 * @param from A list of column names representing the data to bind to the UI. Can be null
337 * if the cursor is not available yet.
338 * @param to The views that should display column in the "from" parameter.
339 * These should all be TextViews. The first N views in this list
340 * are given the values of the first N columns in the from
341 * parameter. Can be null if the cursor is not available yet.
342 */
343 public void changeCursorAndColumns(Cursor c, String[] from, int[] to) {
344 mOriginalFrom = from;
345 mTo = to;
346 super.changeCursor(c);
347 findColumns(mOriginalFrom);
348 }
349
350 /**
351 * This class can be used by external clients of SimpleCursorAdapter
352 * to bind values fom the Cursor to views.
353 *
354 * You should use this class to bind values from the Cursor to views
355 * that are not directly supported by SimpleCursorAdapter or to
356 * change the way binding occurs for views supported by
357 * SimpleCursorAdapter.
358 *
359 * @see SimpleCursorAdapter#bindView(android.view.View, android.content.Context, android.database.Cursor)
360 * @see SimpleCursorAdapter#setViewImage(ImageView, String)
361 * @see SimpleCursorAdapter#setViewText(TextView, String)
362 */
363 public static interface ViewBinder {
364 /**
365 * Binds the Cursor column defined by the specified index to the specified view.
366 *
367 * When binding is handled by this ViewBinder, this method must return true.
368 * If this method returns false, SimpleCursorAdapter will attempts to handle
369 * the binding on its own.
370 *
371 * @param view the view to bind the data to
372 * @param cursor the cursor to get the data from
373 * @param columnIndex the column at which the data can be found in the cursor
374 *
375 * @return true if the data was bound to the view, false otherwise
376 */
377 boolean setViewValue(View view, Cursor cursor, int columnIndex);
378 }
379
380 /**
381 * This class can be used by external clients of SimpleCursorAdapter
382 * to define how the Cursor should be converted to a String.
383 *
384 * @see android.widget.CursorAdapter#convertToString(android.database.Cursor)
385 */
386 public static interface CursorToStringConverter {
387 /**
388 * Returns a CharSequence representing the specified Cursor.
389 *
390 * @param cursor the cursor for which a CharSequence representation
391 * is requested
392 *
393 * @return a non-null CharSequence representing the cursor
394 */
395 CharSequence convertToString(Cursor cursor);
396 }
397
398}