| /* |
| * 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.database.Cursor; |
| import android.net.Uri; |
| import android.view.View; |
| |
| /** |
| * An easy adapter to map columns from a cursor to TextViews or ImageViews |
| * defined in an XML file. You can specify which columns you want, which views |
| * you want to display the columns, and the XML file that defines the appearance |
| * of these views. Separate XML files for child and groups are possible. |
| * |
| * Binding occurs in two phases. First, if a |
| * {@link android.widget.SimpleCursorTreeAdapter.ViewBinder} is available, |
| * {@link ViewBinder#setViewValue(android.view.View, android.database.Cursor, int)} |
| * is invoked. If the returned value is true, binding has occurred. If the |
| * returned value is false and the view to bind is a TextView, |
| * {@link #setViewText(TextView, String)} is invoked. If the returned value |
| * is false and the view to bind is an ImageView, |
| * {@link #setViewImage(ImageView, String)} is invoked. If no appropriate |
| * binding can be found, an {@link IllegalStateException} is thrown. |
| */ |
| public abstract class SimpleCursorTreeAdapter extends ResourceCursorTreeAdapter { |
| |
| /** The name of the columns that contain the data to display for a group. */ |
| private String[] mGroupFromNames; |
| |
| /** The indices of columns that contain data to display for a group. */ |
| private int[] mGroupFrom; |
| /** |
| * The View IDs that will display a group's data fetched from the |
| * corresponding column. |
| */ |
| private int[] mGroupTo; |
| |
| /** The name of the columns that contain the data to display for a child. */ |
| private String[] mChildFromNames; |
| |
| /** The indices of columns that contain data to display for a child. */ |
| private int[] mChildFrom; |
| /** |
| * The View IDs that will display a child's data fetched from the |
| * corresponding column. |
| */ |
| private int[] mChildTo; |
| |
| /** |
| * View binder, if supplied |
| */ |
| private ViewBinder mViewBinder; |
| |
| /** |
| * Constructor. |
| * |
| * @param context The context where the {@link ExpandableListView} |
| * associated with this {@link SimpleCursorTreeAdapter} is |
| * running |
| * @param cursor The database cursor |
| * @param collapsedGroupLayout The resource identifier of a layout file that |
| * defines the views for a collapsed group. The layout file |
| * should include at least those named views defined in groupTo. |
| * @param expandedGroupLayout The resource identifier of a layout file that |
| * defines the views for an expanded group. The layout file |
| * should include at least those named views defined in groupTo. |
| * @param groupFrom A list of column names that will be used to display the |
| * data for a group. |
| * @param groupTo The group views (from the group layouts) that should |
| * display column in the "from" parameter. These should all be |
| * TextViews or ImageViews. The first N views in this list are |
| * given the values of the first N columns in the from parameter. |
| * @param childLayout The resource identifier of a layout file that defines |
| * the views for a child (except the last). The layout file |
| * should include at least those named views defined in childTo. |
| * @param lastChildLayout The resource identifier of a layout file that |
| * defines the views for the last child within a group. The |
| * layout file should include at least those named views defined |
| * in childTo. |
| * @param childFrom A list of column names that will be used to display the |
| * data for a child. |
| * @param childTo The child views (from the child layouts) that should |
| * display column in the "from" parameter. These should all be |
| * TextViews or ImageViews. The first N views in this list are |
| * given the values of the first N columns in the from parameter. |
| */ |
| public SimpleCursorTreeAdapter(Context context, Cursor cursor, int collapsedGroupLayout, |
| int expandedGroupLayout, String[] groupFrom, int[] groupTo, int childLayout, |
| int lastChildLayout, String[] childFrom, int[] childTo) { |
| super(context, cursor, collapsedGroupLayout, expandedGroupLayout, childLayout, |
| lastChildLayout); |
| init(groupFrom, groupTo, childFrom, childTo); |
| } |
| |
| /** |
| * Constructor. |
| * |
| * @param context The context where the {@link ExpandableListView} |
| * associated with this {@link SimpleCursorTreeAdapter} is |
| * running |
| * @param cursor The database cursor |
| * @param collapsedGroupLayout The resource identifier of a layout file that |
| * defines the views for a collapsed group. The layout file |
| * should include at least those named views defined in groupTo. |
| * @param expandedGroupLayout The resource identifier of a layout file that |
| * defines the views for an expanded group. The layout file |
| * should include at least those named views defined in groupTo. |
| * @param groupFrom A list of column names that will be used to display the |
| * data for a group. |
| * @param groupTo The group views (from the group layouts) that should |
| * display column in the "from" parameter. These should all be |
| * TextViews or ImageViews. The first N views in this list are |
| * given the values of the first N columns in the from parameter. |
| * @param childLayout The resource identifier of a layout file that defines |
| * the views for a child. The layout file |
| * should include at least those named views defined in childTo. |
| * @param childFrom A list of column names that will be used to display the |
| * data for a child. |
| * @param childTo The child views (from the child layouts) that should |
| * display column in the "from" parameter. These should all be |
| * TextViews or ImageViews. The first N views in this list are |
| * given the values of the first N columns in the from parameter. |
| */ |
| public SimpleCursorTreeAdapter(Context context, Cursor cursor, int collapsedGroupLayout, |
| int expandedGroupLayout, String[] groupFrom, int[] groupTo, |
| int childLayout, String[] childFrom, int[] childTo) { |
| super(context, cursor, collapsedGroupLayout, expandedGroupLayout, childLayout); |
| init(groupFrom, groupTo, childFrom, childTo); |
| } |
| |
| /** |
| * Constructor. |
| * |
| * @param context The context where the {@link ExpandableListView} |
| * associated with this {@link SimpleCursorTreeAdapter} is |
| * running |
| * @param cursor The database cursor |
| * @param groupLayout The resource identifier of a layout file that defines |
| * the views for a group. The layout file should include at least |
| * those named views defined in groupTo. |
| * @param groupFrom A list of column names that will be used to display the |
| * data for a group. |
| * @param groupTo The group views (from the group layouts) that should |
| * display column in the "from" parameter. These should all be |
| * TextViews or ImageViews. The first N views in this list are |
| * given the values of the first N columns in the from parameter. |
| * @param childLayout The resource identifier of a layout file that defines |
| * the views for a child. The layout file should include at least |
| * those named views defined in childTo. |
| * @param childFrom A list of column names that will be used to display the |
| * data for a child. |
| * @param childTo The child views (from the child layouts) that should |
| * display column in the "from" parameter. These should all be |
| * TextViews or ImageViews. The first N views in this list are |
| * given the values of the first N columns in the from parameter. |
| */ |
| public SimpleCursorTreeAdapter(Context context, Cursor cursor, int groupLayout, |
| String[] groupFrom, int[] groupTo, int childLayout, String[] childFrom, |
| int[] childTo) { |
| super(context, cursor, groupLayout, childLayout); |
| init(groupFrom, groupTo, childFrom, childTo); |
| } |
| |
| private void init(String[] groupFromNames, int[] groupTo, String[] childFromNames, |
| int[] childTo) { |
| |
| mGroupFromNames = groupFromNames; |
| mGroupTo = groupTo; |
| |
| mChildFromNames = childFromNames; |
| mChildTo = childTo; |
| } |
| |
| /** |
| * Returns the {@link ViewBinder} used to bind data to views. |
| * |
| * @return a ViewBinder or null if the binder does not exist |
| * |
| * @see #setViewBinder(android.widget.SimpleCursorTreeAdapter.ViewBinder) |
| */ |
| public ViewBinder getViewBinder() { |
| return mViewBinder; |
| } |
| |
| /** |
| * Sets the binder used to bind data to views. |
| * |
| * @param viewBinder the binder used to bind data to views, can be null to |
| * remove the existing binder |
| * |
| * @see #getViewBinder() |
| */ |
| public void setViewBinder(ViewBinder viewBinder) { |
| mViewBinder = viewBinder; |
| } |
| |
| private void bindView(View view, Context context, Cursor cursor, int[] from, int[] to) { |
| final ViewBinder binder = mViewBinder; |
| |
| for (int i = 0; i < to.length; i++) { |
| View v = view.findViewById(to[i]); |
| if (v != null) { |
| boolean bound = false; |
| if (binder != null) { |
| bound = binder.setViewValue(v, cursor, from[i]); |
| } |
| |
| if (!bound) { |
| String text = cursor.getString(from[i]); |
| if (text == null) { |
| text = ""; |
| } |
| if (v instanceof TextView) { |
| setViewText((TextView) v, text); |
| } else if (v instanceof ImageView) { |
| setViewImage((ImageView) v, text); |
| } else { |
| throw new IllegalStateException("SimpleCursorTreeAdapter can bind values" + |
| " only to TextView and ImageView!"); |
| } |
| } |
| } |
| } |
| } |
| |
| private void initFromColumns(Cursor cursor, String[] fromColumnNames, int[] fromColumns) { |
| for (int i = fromColumnNames.length - 1; i >= 0; i--) { |
| fromColumns[i] = cursor.getColumnIndexOrThrow(fromColumnNames[i]); |
| } |
| } |
| |
| @Override |
| protected void bindChildView(View view, Context context, Cursor cursor, boolean isLastChild) { |
| if (mChildFrom == null) { |
| mChildFrom = new int[mChildFromNames.length]; |
| initFromColumns(cursor, mChildFromNames, mChildFrom); |
| } |
| |
| bindView(view, context, cursor, mChildFrom, mChildTo); |
| } |
| |
| @Override |
| protected void bindGroupView(View view, Context context, Cursor cursor, boolean isExpanded) { |
| if (mGroupFrom == null) { |
| mGroupFrom = new int[mGroupFromNames.length]; |
| initFromColumns(cursor, mGroupFromNames, mGroupFrom); |
| } |
| |
| bindView(view, context, cursor, mGroupFrom, mGroupTo); |
| } |
| |
| /** |
| * Called by bindView() to set the image for an ImageView. By default, the |
| * value will be treated as a Uri. Intended to be overridden by Adapters |
| * that need to filter strings retrieved from the database. |
| * |
| * @param v ImageView to receive an image |
| * @param value the value retrieved from the cursor |
| */ |
| protected void setViewImage(ImageView v, String value) { |
| try { |
| v.setImageResource(Integer.parseInt(value)); |
| } catch (NumberFormatException nfe) { |
| v.setImageURI(Uri.parse(value)); |
| } |
| } |
| |
| /** |
| * Called by bindView() to set the text for a TextView but only if |
| * there is no existing ViewBinder or if the existing ViewBinder cannot |
| * handle binding to a TextView. |
| * |
| * Intended to be overridden by Adapters that need to filter strings |
| * retrieved from the database. |
| * |
| * @param v TextView to receive text |
| * @param text the text to be set for the TextView |
| */ |
| public void setViewText(TextView v, String text) { |
| v.setText(text); |
| } |
| |
| /** |
| * This class can be used by external clients of SimpleCursorTreeAdapter |
| * to bind values from the Cursor to views. |
| * |
| * You should use this class to bind values from the Cursor to views |
| * that are not directly supported by SimpleCursorTreeAdapter or to |
| * change the way binding occurs for views supported by |
| * SimpleCursorTreeAdapter. |
| * |
| * @see SimpleCursorTreeAdapter#setViewImage(ImageView, String) |
| * @see SimpleCursorTreeAdapter#setViewText(TextView, String) |
| */ |
| public static interface ViewBinder { |
| /** |
| * Binds the Cursor column defined by the specified index to the specified view. |
| * |
| * When binding is handled by this ViewBinder, this method must return true. |
| * If this method returns false, SimpleCursorTreeAdapter will attempts to handle |
| * the binding on its own. |
| * |
| * @param view the view to bind the data to |
| * @param cursor the cursor to get the data from |
| * @param columnIndex the column at which the data can be found in the cursor |
| * |
| * @return true if the data was bound to the view, false otherwise |
| */ |
| boolean setViewValue(View view, Cursor cursor, int columnIndex); |
| } |
| } |