SimpleAdapter.java revision c651e4d34f0c6dca5d6675cec54c7027e2e7dd58
1b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera/* 2b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * Copyright (C) 2006 The Android Open Source Project 3b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * 4b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * Licensed under the Apache License, Version 2.0 (the "License"); 5b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * you may not use this file except in compliance with the License. 6b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * You may obtain a copy of the License at 7b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * 8b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * http://www.apache.org/licenses/LICENSE-2.0 9b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * 10b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * Unless required by applicable law or agreed to in writing, software 11b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * distributed under the License is distributed on an "AS IS" BASIS, 12b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * See the License for the specific language governing permissions and 14b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * limitations under the License. 15b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera */ 16b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera 17b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talaverapackage android.widget; 18b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera 19dc589ac82b5fe2063f4cfd94c8ae26d43d5420a0Sudheer Shankaimport android.annotation.IdRes; 206bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolovimport android.annotation.LayoutRes; 21afad8783699b1ba6f3c7ee5961d6ddc2bd771dc1Alan Treadwayimport android.content.Context; 22b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talaveraimport android.content.res.Resources; 239c17388cff98fba9679ce6457ac5003a660c6013Esteban Talaveraimport android.net.Uri; 24b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talaveraimport android.view.ContextThemeWrapper; 25b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talaveraimport android.view.LayoutInflater; 26b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talaveraimport android.view.View; 279c17388cff98fba9679ce6457ac5003a660c6013Esteban Talaveraimport android.view.ViewGroup; 28b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera 29b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talaveraimport java.util.ArrayList; 30b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talaveraimport java.util.List; 31b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talaveraimport java.util.Map; 32b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera 33b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera/** 34b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * An easy adapter to map static data to views defined in an XML file. You can specify the data 35b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * backing the list as an ArrayList of Maps. Each entry in the ArrayList corresponds to one row 36b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * in the list. The Maps contain the data for each row. You also specify an XML file that 37b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * defines the views used to display the row, and a mapping from keys in the Map to specific 38b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * views. 39b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * 40b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * Binding data to views occurs in two phases. First, if a 41b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * {@link android.widget.SimpleAdapter.ViewBinder} is available, 42b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * {@link ViewBinder#setViewValue(android.view.View, Object, String)} 43b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * is invoked. If the returned value is true, binding has occurred. 44e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban * If the returned value is false, the following views are then tried in order: 45b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * <ul> 4641de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera * <li> A view that implements Checkable (e.g. CheckBox). The expected bind value is a boolean. 4738dcca51a739d3273b24e84ba5e89e505f45960cKenny Guy * <li> TextView. The expected bind value is a string and {@link #setViewText(TextView, String)} 48b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * is invoked. 49b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * <li> ImageView. The expected bind value is a resource id or a string and 50b52c7330d986e62812fd7c1b77020629e8ff7930Xiaohui Chen * {@link #setViewImage(ImageView, int)} or {@link #setViewImage(ImageView, String)} is invoked. 51a52562ca9a4144cf30e6d5c6ffe856cc8e284464Makoto Onuki * </ul> 52e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban * If no appropriate binding can be found, an {@link IllegalStateException} is thrown. 53b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera */ 54b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talaverapublic class SimpleAdapter extends BaseAdapter implements Filterable, ThemedSpinnerAdapter { 55b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera private final LayoutInflater mInflater; 569c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera 579c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera private int[] mTo; 586bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov private String[] mFrom; 5958b684f1cdc52467b71c42cfae18433a19ce7d0bMakoto Onuki private ViewBinder mViewBinder; 606bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov 616bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov private List<? extends Map<String, ?>> mData; 626bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov 636bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov private int mResource; 6438dcca51a739d3273b24e84ba5e89e505f45960cKenny Guy private int mDropDownResource; 6538dcca51a739d3273b24e84ba5e89e505f45960cKenny Guy 66b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera /** Layout inflater used for {@link #getDropDownView(int, View, ViewGroup)}. */ 67e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban private LayoutInflater mDropDownInflater; 68e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban 69e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban private SimpleFilter mFilter; 706bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov private ArrayList<Map<String, ?>> mUnfilteredData; 716bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov 7241de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera /** 7341de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera * Constructor 7438dcca51a739d3273b24e84ba5e89e505f45960cKenny Guy * 7538dcca51a739d3273b24e84ba5e89e505f45960cKenny Guy * @param context The context where the View associated with this SimpleAdapter is running 7638dcca51a739d3273b24e84ba5e89e505f45960cKenny Guy * @param data A List of Maps. Each entry in the List corresponds to one row in the list. The 7738dcca51a739d3273b24e84ba5e89e505f45960cKenny Guy * Maps contain the data for each row, and should include all the entries specified in 7838dcca51a739d3273b24e84ba5e89e505f45960cKenny Guy * "from" 79b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * @param resource Resource identifier of a view layout that defines the views for this list 80b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * item. The layout file should include at least those named views defined in "to" 81b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * @param from A list of column names that will be added to the Map associated with each 82b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * item. 83b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * @param to The views that should display column in the "from" parameter. These should all be 84b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * TextViews. The first N views in this list are given the values of the first N columns 85b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * in the from parameter. 86b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera */ 87b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera public SimpleAdapter(Context context, List<? extends Map<String, ?>> data, 88b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera @LayoutRes int resource, String[] from, @IdRes int[] to) { 89b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera mData = data; 90b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera mResource = mDropDownResource = resource; 91b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera mFrom = from; 92e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban mTo = to; 93e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 94e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban } 95b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera 9641de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera /** 9741de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera * @see android.widget.Adapter#getCount() 9841de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera */ 9941de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera public int getCount() { 100b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera return mData.size(); 10138dcca51a739d3273b24e84ba5e89e505f45960cKenny Guy } 10238dcca51a739d3273b24e84ba5e89e505f45960cKenny Guy 10338dcca51a739d3273b24e84ba5e89e505f45960cKenny Guy /** 104b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera * @see android.widget.Adapter#getItem(int) 1059c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera */ 106b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera public Object getItem(int position) { 107b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera return mData.get(position); 108b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera } 1096bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov 110a52562ca9a4144cf30e6d5c6ffe856cc8e284464Makoto Onuki /** 111a52562ca9a4144cf30e6d5c6ffe856cc8e284464Makoto Onuki * @see android.widget.Adapter#getItemId(int) 1126bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov */ 1136bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov public long getItemId(int position) { 1146bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov return position; 1156bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov } 1166bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov 1176bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov /** 1186bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov * @see android.widget.Adapter#getView(int, View, ViewGroup) 1196bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov */ 120dc589ac82b5fe2063f4cfd94c8ae26d43d5420a0Sudheer Shanka public View getView(int position, View convertView, ViewGroup parent) { 1216bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov return createViewFromResource(mInflater, position, convertView, parent, mResource); 1226bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov } 1236bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov 1246bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov private View createViewFromResource(LayoutInflater inflater, int position, View convertView, 1256bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov ViewGroup parent, int resource) { 1266bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov View v; 127a52562ca9a4144cf30e6d5c6ffe856cc8e284464Makoto Onuki if (convertView == null) { 128a52562ca9a4144cf30e6d5c6ffe856cc8e284464Makoto Onuki v = inflater.inflate(resource, parent, false); 129a52562ca9a4144cf30e6d5c6ffe856cc8e284464Makoto Onuki } else { 130a52562ca9a4144cf30e6d5c6ffe856cc8e284464Makoto Onuki v = convertView; 131a52562ca9a4144cf30e6d5c6ffe856cc8e284464Makoto Onuki } 132e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban 133a52562ca9a4144cf30e6d5c6ffe856cc8e284464Makoto Onuki bindView(position, v); 134e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban 135e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban return v; 136e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban } 1376bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov 138e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban /** 139e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban * <p>Sets the layout resource to create the drop down views.</p> 140e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban * 141e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban * @param resource the layout resource defining the drop down views 142e9119876a21575ee7a7d058da85d04c4c4b8a971Zoltan Szatmary-Ban * @see #getDropDownView(int, android.view.View, android.view.ViewGroup) 14341de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera */ 1446bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov public void setDropDownViewResource(int resource) { 14558b684f1cdc52467b71c42cfae18433a19ce7d0bMakoto Onuki mDropDownResource = resource; 1469c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera } 1479c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera 148a52562ca9a4144cf30e6d5c6ffe856cc8e284464Makoto Onuki /** 14941de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera * Sets the {@link android.content.res.Resources.Theme} against which drop-down views are 150a52562ca9a4144cf30e6d5c6ffe856cc8e284464Makoto Onuki * inflated. 1519c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera * <p> 1529c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera * By default, drop-down views are inflated against the theme of the 1539c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera * {@link Context} passed to the adapter's constructor. 15458b684f1cdc52467b71c42cfae18433a19ce7d0bMakoto Onuki * 1559c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera * @param theme the theme against which to inflate drop-down views or 1569c17388cff98fba9679ce6457ac5003a660c6013Esteban Talavera * {@code null} to use the theme from the adapter's context 157afad8783699b1ba6f3c7ee5961d6ddc2bd771dc1Alan Treadway * @see #getDropDownView(int, View, ViewGroup) 158afad8783699b1ba6f3c7ee5961d6ddc2bd771dc1Alan Treadway */ 159afad8783699b1ba6f3c7ee5961d6ddc2bd771dc1Alan Treadway @Override 160afad8783699b1ba6f3c7ee5961d6ddc2bd771dc1Alan Treadway public void setDropDownViewTheme(Resources.Theme theme) { 161a52562ca9a4144cf30e6d5c6ffe856cc8e284464Makoto Onuki if (theme == null) { 16258b684f1cdc52467b71c42cfae18433a19ce7d0bMakoto Onuki mDropDownInflater = null; 163b5ef162129ced7e9636052af6b7f08d677a01f13Esteban Talavera } else if (theme == mInflater.getContext().getTheme()) { 16441de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera mDropDownInflater = mInflater; 16538dcca51a739d3273b24e84ba5e89e505f45960cKenny Guy } else { 16638dcca51a739d3273b24e84ba5e89e505f45960cKenny Guy final Context context = new ContextThemeWrapper(mInflater.getContext(), theme); 16738dcca51a739d3273b24e84ba5e89e505f45960cKenny Guy mDropDownInflater = LayoutInflater.from(context); 16838dcca51a739d3273b24e84ba5e89e505f45960cKenny Guy } 16938dcca51a739d3273b24e84ba5e89e505f45960cKenny Guy } 17038dcca51a739d3273b24e84ba5e89e505f45960cKenny Guy 17141de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera @Override 1726bccb76a64ba74c2e0267db1d2ec14a4ffa96771Fyodor Kupolov public Resources.Theme getDropDownViewTheme() { 173474c7aceae0c6a91049deb7db944cbe85b56bcc7Sudheer Shanka return mDropDownInflater == null ? null : mDropDownInflater.getContext().getTheme(); 17441de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera } 17541de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera 176a52562ca9a4144cf30e6d5c6ffe856cc8e284464Makoto Onuki @Override 177474c7aceae0c6a91049deb7db944cbe85b56bcc7Sudheer Shanka public View getDropDownView(int position, View convertView, ViewGroup parent) { 178474c7aceae0c6a91049deb7db944cbe85b56bcc7Sudheer Shanka final LayoutInflater inflater = mDropDownInflater == null ? mInflater : mDropDownInflater; 17941de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera return createViewFromResource(inflater, position, convertView, parent, mDropDownResource); 18041de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera } 18141de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera 182474c7aceae0c6a91049deb7db944cbe85b56bcc7Sudheer Shanka private void bindView(int position, View view) { 18341de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera final Map dataSet = mData.get(position); 18441de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera if (dataSet == null) { 185afad8783699b1ba6f3c7ee5961d6ddc2bd771dc1Alan Treadway return; 186afad8783699b1ba6f3c7ee5961d6ddc2bd771dc1Alan Treadway } 187afad8783699b1ba6f3c7ee5961d6ddc2bd771dc1Alan Treadway 188afad8783699b1ba6f3c7ee5961d6ddc2bd771dc1Alan Treadway final ViewBinder binder = mViewBinder; 189c48bca50fa64765d3019b0bf82511e030cabcc7aEsteban Talavera final String[] from = mFrom; 190474c7aceae0c6a91049deb7db944cbe85b56bcc7Sudheer Shanka final int[] to = mTo; 19141de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera final int count = to.length; 19241de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera 19341de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera for (int i = 0; i < count; i++) { 19441de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera final View v = view.findViewById(to[i]); 19541de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera if (v != null) { 19641de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera final Object data = dataSet.get(from[i]); 19741de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera String text = data == null ? "" : data.toString(); 19841de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera if (text == null) { 19941de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera text = ""; 20041de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera } 20141de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera 20241de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera boolean bound = false; 20341de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera if (binder != null) { 20441de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera bound = binder.setViewValue(v, data, text); 20541de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera } 20641de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera 20741de9bb6fda113f7cfb8b7b8d64d07d3809f8f20Esteban Talavera if (!bound) { 208afad8783699b1ba6f3c7ee5961d6ddc2bd771dc1Alan Treadway if (v instanceof Checkable) { 209 if (data instanceof Boolean) { 210 ((Checkable) v).setChecked((Boolean) data); 211 } else if (v instanceof TextView) { 212 // Note: keep the instanceof TextView check at the bottom of these 213 // ifs since a lot of views are TextViews (e.g. CheckBoxes). 214 setViewText((TextView) v, text); 215 } else { 216 throw new IllegalStateException(v.getClass().getName() + 217 " should be bound to a Boolean, not a " + 218 (data == null ? "<unknown type>" : data.getClass())); 219 } 220 } else if (v instanceof TextView) { 221 // Note: keep the instanceof TextView check at the bottom of these 222 // ifs since a lot of views are TextViews (e.g. CheckBoxes). 223 setViewText((TextView) v, text); 224 } else if (v instanceof ImageView) { 225 if (data instanceof Integer) { 226 setViewImage((ImageView) v, (Integer) data); 227 } else { 228 setViewImage((ImageView) v, text); 229 } 230 } else { 231 throw new IllegalStateException(v.getClass().getName() + " is not a " + 232 " view that can be bounds by this SimpleAdapter"); 233 } 234 } 235 } 236 } 237 } 238 239 /** 240 * Returns the {@link ViewBinder} used to bind data to views. 241 * 242 * @return a ViewBinder or null if the binder does not exist 243 * 244 * @see #setViewBinder(android.widget.SimpleAdapter.ViewBinder) 245 */ 246 public ViewBinder getViewBinder() { 247 return mViewBinder; 248 } 249 250 /** 251 * Sets the binder used to bind data to views. 252 * 253 * @param viewBinder the binder used to bind data to views, can be null to 254 * remove the existing binder 255 * 256 * @see #getViewBinder() 257 */ 258 public void setViewBinder(ViewBinder viewBinder) { 259 mViewBinder = viewBinder; 260 } 261 262 /** 263 * Called by bindView() to set the image for an ImageView but only if 264 * there is no existing ViewBinder or if the existing ViewBinder cannot 265 * handle binding to an ImageView. 266 * 267 * This method is called instead of {@link #setViewImage(ImageView, String)} 268 * if the supplied data is an int or Integer. 269 * 270 * @param v ImageView to receive an image 271 * @param value the value retrieved from the data set 272 * 273 * @see #setViewImage(ImageView, String) 274 */ 275 public void setViewImage(ImageView v, int value) { 276 v.setImageResource(value); 277 } 278 279 /** 280 * Called by bindView() to set the image for an ImageView but only if 281 * there is no existing ViewBinder or if the existing ViewBinder cannot 282 * handle binding to an ImageView. 283 * 284 * By default, the value will be treated as an image resource. If the 285 * value cannot be used as an image resource, the value is used as an 286 * image Uri. 287 * 288 * This method is called instead of {@link #setViewImage(ImageView, int)} 289 * if the supplied data is not an int or Integer. 290 * 291 * @param v ImageView to receive an image 292 * @param value the value retrieved from the data set 293 * 294 * @see #setViewImage(ImageView, int) 295 */ 296 public void setViewImage(ImageView v, String value) { 297 try { 298 v.setImageResource(Integer.parseInt(value)); 299 } catch (NumberFormatException nfe) { 300 v.setImageURI(Uri.parse(value)); 301 } 302 } 303 304 /** 305 * Called by bindView() to set the text for a TextView but only if 306 * there is no existing ViewBinder or if the existing ViewBinder cannot 307 * handle binding to a TextView. 308 * 309 * @param v TextView to receive text 310 * @param text the text to be set for the TextView 311 */ 312 public void setViewText(TextView v, String text) { 313 v.setText(text); 314 } 315 316 public Filter getFilter() { 317 if (mFilter == null) { 318 mFilter = new SimpleFilter(); 319 } 320 return mFilter; 321 } 322 323 /** 324 * This class can be used by external clients of SimpleAdapter to bind 325 * values to views. 326 * 327 * You should use this class to bind values to views that are not 328 * directly supported by SimpleAdapter or to change the way binding 329 * occurs for views supported by SimpleAdapter. 330 * 331 * @see SimpleAdapter#setViewImage(ImageView, int) 332 * @see SimpleAdapter#setViewImage(ImageView, String) 333 * @see SimpleAdapter#setViewText(TextView, String) 334 */ 335 public static interface ViewBinder { 336 /** 337 * Binds the specified data to the specified view. 338 * 339 * When binding is handled by this ViewBinder, this method must return true. 340 * If this method returns false, SimpleAdapter will attempts to handle 341 * the binding on its own. 342 * 343 * @param view the view to bind the data to 344 * @param data the data to bind to the view 345 * @param textRepresentation a safe String representation of the supplied data: 346 * it is either the result of data.toString() or an empty String but it 347 * is never null 348 * 349 * @return true if the data was bound to the view, false otherwise 350 */ 351 boolean setViewValue(View view, Object data, String textRepresentation); 352 } 353 354 /** 355 * <p>An array filters constrains the content of the array adapter with 356 * a prefix. Each item that does not start with the supplied prefix 357 * is removed from the list.</p> 358 */ 359 private class SimpleFilter extends Filter { 360 361 @Override 362 protected FilterResults performFiltering(CharSequence prefix) { 363 FilterResults results = new FilterResults(); 364 365 if (mUnfilteredData == null) { 366 mUnfilteredData = new ArrayList<Map<String, ?>>(mData); 367 } 368 369 if (prefix == null || prefix.length() == 0) { 370 ArrayList<Map<String, ?>> list = mUnfilteredData; 371 results.values = list; 372 results.count = list.size(); 373 } else { 374 String prefixString = prefix.toString().toLowerCase(); 375 376 ArrayList<Map<String, ?>> unfilteredValues = mUnfilteredData; 377 int count = unfilteredValues.size(); 378 379 ArrayList<Map<String, ?>> newValues = new ArrayList<Map<String, ?>>(count); 380 381 for (int i = 0; i < count; i++) { 382 Map<String, ?> h = unfilteredValues.get(i); 383 if (h != null) { 384 385 int len = mTo.length; 386 387 for (int j=0; j<len; j++) { 388 String str = (String)h.get(mFrom[j]); 389 390 String[] words = str.split(" "); 391 int wordCount = words.length; 392 393 for (int k = 0; k < wordCount; k++) { 394 String word = words[k]; 395 396 if (word.toLowerCase().startsWith(prefixString)) { 397 newValues.add(h); 398 break; 399 } 400 } 401 } 402 } 403 } 404 405 results.values = newValues; 406 results.count = newValues.size(); 407 } 408 409 return results; 410 } 411 412 @Override 413 protected void publishResults(CharSequence constraint, FilterResults results) { 414 //noinspection unchecked 415 mData = (List<Map<String, ?>>) results.values; 416 if (results.count > 0) { 417 notifyDataSetChanged(); 418 } else { 419 notifyDataSetInvalidated(); 420 } 421 } 422 } 423} 424