ArrayAdapter.java revision b9ead4a91599ca63e947f74f83b67a58bda64a82
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
209b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Liimport android.content.res.Resources;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
229b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Liimport android.view.ContextThemeWrapper;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.LayoutInflater;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewGroup;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Arrays;
29a696f5d667227365da732481770767dcb330dd23Mathias Agopianimport java.util.Collection;
30fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennisimport java.util.Collections;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Comparator;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A concrete BaseAdapter that is backed by an array of arbitrary
36bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor * objects.  By default this class expects that the provided resource id references
37bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor * a single TextView.  If you want to use a more complex layout, use the constructors that
38bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor * also takes a field id.  That field id should reference a TextView in the larger layout
39df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main * resource.
40bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor *
417478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li * <p>However the TextView is referenced, it will be filled with the toString() of each object in
42df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main * the array. You can add lists or arrays of custom objects. Override the toString() method
43df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main * of your objects to determine what text will be displayed for the item in the list.
44bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor *
457478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li * <p>To use something other than TextViews for the array display, for instance, ImageViews,
46df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main * or to have some of data besides toString() results fill the views,
47df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main * override {@link #getView(int, View, ViewGroup)} to return the type of view you want.
48df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main */
49df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Mainpublic class ArrayAdapter<T> extends BaseAdapter implements Filterable,
50df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main        Spinner.ThemedSpinnerAdapter {
51bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    /**
52bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * Contains the list of objects that represent the data of this ArrayAdapter.
53bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * The content of this list is referred to as "the array" in the documentation.
54341ff13689dfe822b598e626272ac2e80041b482Dan Egnor     */
55bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    private List<T> mObjects;
56bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
57bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    /**
58bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * Lock used to modify the content of {@link #mObjects}. Any write operation
59bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * performed on the array should be synchronized on this lock. This lock is also
60bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * used by the filter (see {@link #getFilter()} to make a synchronized copy of
61bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * the original array of data.
62bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     */
63bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    private final Object mLock = new Object();
64bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
65bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    /**
66bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * The resource indicating what views to inflate to display the content of this
67bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * array adapter.
68bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     */
69bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    private int mResource;
70bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
71bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    /**
72bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * The resource indicating what views to inflate to display the content of this
73bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * array adapter in a drop down widget.
74bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     */
75bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    private int mDropDownResource;
76bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
77bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    /**
78bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * If the inflated resource is not a TextView, {@link #mFieldId} is used to find
79bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * a TextView inside the inflated views hierarchy. This field must contain the
80bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * identifier that matches the one defined in the resource file.
81bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     */
82bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    private int mFieldId = 0;
83bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
84bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    /**
85bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * Indicates whether or not {@link #notifyDataSetChanged()} must be called whenever
86bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * {@link #mObjects} is modified.
87bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     */
88bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    private boolean mNotifyOnChange = true;
89bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
90bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    private Context mContext;
91bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
92bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    // A copy of the original mObjects array, initialized from and then used instead as soon as
93bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    // the mFilter ArrayFilter is used. mObjects will then only contain the filtered values.
94bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    private ArrayList<T> mOriginalValues;
95bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    private ArrayFilter mFilter;
96bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
97bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    private LayoutInflater mInflater;
98bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
99bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    /** Layout inflater used for {@link #getDropDownView(int, View, ViewGroup)}. */
100bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    private LayoutInflater mDropDownInflater;
101bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
102bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    /**
103bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * Constructor
104bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     *
105bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * @param context The current context.
106341ff13689dfe822b598e626272ac2e80041b482Dan Egnor     * @param resource The resource ID for a layout file containing a TextView to use when
107bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     *                 instantiating views.
108bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     */
109df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main    public ArrayAdapter(Context context, int resource) {
110df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main        this(context, resource, 0, new ArrayList<T>());
111df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main    }
1127478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li
113df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main    /**
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Constructor
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context The current context.
1179b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li     * @param resource The resource ID for a layout file containing a layout to use when
118d2c2929c94bec68741b85f4174e11307fb65157fWu-cheng Li     *                 instantiating views.
119da83f4674a564007baac03db062a289c8158d940Benny Wong     * @param textViewResourceId The id of the TextView within the layout resource to be populated
120da83f4674a564007baac03db062a289c8158d940Benny Wong     */
121da83f4674a564007baac03db062a289c8158d940Benny Wong    public ArrayAdapter(Context context, int resource, int textViewResourceId) {
122da83f4674a564007baac03db062a289c8158d940Benny Wong        this(context, resource, textViewResourceId, new ArrayList<T>());
123da83f4674a564007baac03db062a289c8158d940Benny Wong    }
124da83f4674a564007baac03db062a289c8158d940Benny Wong
125da83f4674a564007baac03db062a289c8158d940Benny Wong    /**
126da83f4674a564007baac03db062a289c8158d940Benny Wong     * Constructor
127da83f4674a564007baac03db062a289c8158d940Benny Wong     *
128da83f4674a564007baac03db062a289c8158d940Benny Wong     * @param context The current context.
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param resource The resource ID for a layout file containing a TextView to use when
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 instantiating views.
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param objects The objects to represent in the ListView.
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ArrayAdapter(Context context, int resource, T[] objects) {
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(context, resource, 0, Arrays.asList(objects));
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
136e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1383f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li     * Constructor
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context The current context.
14194927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp     * @param resource The resource ID for a layout file containing a layout to use when
1429b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li     *                 instantiating views.
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param textViewResourceId The id of the TextView within the layout resource to be populated
144341ff13689dfe822b598e626272ac2e80041b482Dan Egnor     * @param objects The objects to represent in the ListView.
145e25cc656392d8866e163f78b60c7791455d0fb44Chih-Chung Chang     */
146e25cc656392d8866e163f78b60c7791455d0fb44Chih-Chung Chang    public ArrayAdapter(Context context, int resource, int textViewResourceId, T[] objects) {
147e25cc656392d8866e163f78b60c7791455d0fb44Chih-Chung Chang        this(context, resource, textViewResourceId, Arrays.asList(objects));
148e25cc656392d8866e163f78b60c7791455d0fb44Chih-Chung Chang    }
149341ff13689dfe822b598e626272ac2e80041b482Dan Egnor
150b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang    /**
151b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang     * Constructor
152b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang     *
153b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang     * @param context The current context.
154b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang     * @param resource The resource ID for a layout file containing a TextView to use when
155b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang     *                 instantiating views.
156b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang     * @param objects The objects to represent in the ListView.
157b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang     */
1587836660f5eb45b7b7e1f5119face65c80e2ade17Wu-cheng Li    public ArrayAdapter(Context context, int resource, List<T> objects) {
1597836660f5eb45b7b7e1f5119face65c80e2ade17Wu-cheng Li        this(context, resource, 0, objects);
1607836660f5eb45b7b7e1f5119face65c80e2ade17Wu-cheng Li    }
161b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang
1627836660f5eb45b7b7e1f5119face65c80e2ade17Wu-cheng Li    /**
1637836660f5eb45b7b7e1f5119face65c80e2ade17Wu-cheng Li     * Constructor
1647836660f5eb45b7b7e1f5119face65c80e2ade17Wu-cheng Li     *
1657836660f5eb45b7b7e1f5119face65c80e2ade17Wu-cheng Li     * @param context The current context.
166b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang     * @param resource The resource ID for a layout file containing a layout to use when
167b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang     *                 instantiating views.
168b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang     * @param textViewResourceId The id of the TextView within the layout resource to be populated
169b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang     * @param objects The objects to represent in the ListView.
170b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang     */
171b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang    public ArrayAdapter(Context context, int resource, int textViewResourceId, List<T> objects) {
1727836660f5eb45b7b7e1f5119face65c80e2ade17Wu-cheng Li        mContext = context;
173b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang        mInflater = LayoutInflater.from(context);
174b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang        mResource = mDropDownResource = resource;
175b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang        mObjects = objects;
176b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang        mFieldId = textViewResourceId;
177b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang    }
178b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang
1792fe6fcaff4bdab45484055d6c18dd96d1b7b7be1Wu-cheng Li    /**
1802fe6fcaff4bdab45484055d6c18dd96d1b7b7be1Wu-cheng Li     * Adds the specified object at the end of the array.
1812fe6fcaff4bdab45484055d6c18dd96d1b7b7be1Wu-cheng Li     *
1822fe6fcaff4bdab45484055d6c18dd96d1b7b7be1Wu-cheng Li     * @param object The object to add at the end of the array.
1832fe6fcaff4bdab45484055d6c18dd96d1b7b7be1Wu-cheng Li     */
1842fe6fcaff4bdab45484055d6c18dd96d1b7b7be1Wu-cheng Li    public void add(T object) {
185b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang        synchronized (mLock) {
186b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang            if (mOriginalValues != null) {
18769ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick                mOriginalValues.add(object);
18869ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick            } else {
18969ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick                mObjects.add(object);
19069ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick            }
191b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang        }
1927836660f5eb45b7b7e1f5119face65c80e2ade17Wu-cheng Li        if (mNotifyOnChange) notifyDataSetChanged();
193b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang    }
194b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang
195b8bb78f54b48868465a9d69d65fda08524ab5ae1Chih-Chung Chang    /**
196341ff13689dfe822b598e626272ac2e80041b482Dan Egnor     * Adds the specified Collection at the end of the array.
197bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     *
198bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * @param collection The Collection to add at the end of the array.
199bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     */
200bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    public void addAll(Collection<? extends T> collection) {
201341ff13689dfe822b598e626272ac2e80041b482Dan Egnor        synchronized (mLock) {
202341ff13689dfe822b598e626272ac2e80041b482Dan Egnor            if (mOriginalValues != null) {
203bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor                mOriginalValues.addAll(collection);
204bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor            } else {
205bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor                mObjects.addAll(collection);
206bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor            }
207bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor        }
208bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor        if (mNotifyOnChange) notifyDataSetChanged();
209bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    }
210bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
211bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    /**
212bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * Adds the specified items at the end of the array.
213bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     *
214341ff13689dfe822b598e626272ac2e80041b482Dan Egnor     * @param items The items to add at the end of the array.
215a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li     */
216bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    public void addAll(T ... items) {
217bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor        synchronized (mLock) {
218bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor            if (mOriginalValues != null) {
219e25cc656392d8866e163f78b60c7791455d0fb44Chih-Chung Chang                Collections.addAll(mOriginalValues, items);
220e25cc656392d8866e163f78b60c7791455d0fb44Chih-Chung Chang            } else {
221e25cc656392d8866e163f78b60c7791455d0fb44Chih-Chung Chang                Collections.addAll(mObjects, items);
222e25cc656392d8866e163f78b60c7791455d0fb44Chih-Chung Chang            }
223e25cc656392d8866e163f78b60c7791455d0fb44Chih-Chung Chang        }
224e25cc656392d8866e163f78b60c7791455d0fb44Chih-Chung Chang        if (mNotifyOnChange) notifyDataSetChanged();
225a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li    }
226a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li
227a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li    /**
2287836660f5eb45b7b7e1f5119face65c80e2ade17Wu-cheng Li     * Inserts the specified object at the specified index in the array.
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2309b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li     * @param object The object to insert into the array.
231a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li     * @param index The index at which the object must be inserted.
232a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li     */
233a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li    public void insert(T object, int index) {
234a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li        synchronized (mLock) {
235a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li            if (mOriginalValues != null) {
236a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li                mOriginalValues.add(index, object);
237a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li            } else {
238a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li                mObjects.add(index, object);
239a48b70fa8ff6363d1e5282be70f6be12bc0688dcWu-cheng Li            }
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mNotifyOnChange) notifyDataSetChanged();
242e25cc656392d8866e163f78b60c7791455d0fb44Chih-Chung Chang    }
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Removes the specified object from the array.
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
247e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks     * @param object The object to remove.
2483f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li     */
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void remove(T object) {
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mLock) {
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mOriginalValues != null) {
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mOriginalValues.remove(object);
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mObjects.remove(object);
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mNotifyOnChange) notifyDataSetChanged();
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
259e25cc656392d8866e163f78b60c7791455d0fb44Chih-Chung Chang
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2619b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li     * Remove all elements from the list.
2629b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li     */
2639b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li    public void clear() {
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mLock) {
2659b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li            if (mOriginalValues != null) {
266e25cc656392d8866e163f78b60c7791455d0fb44Chih-Chung Chang                mOriginalValues.clear();
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
2689b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li                mObjects.clear();
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mNotifyOnChange) notifyDataSetChanged();
272bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    }
273bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2759b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li     * Sorts the content of this adapter using the specified comparator.
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param comparator The comparator used to sort the objects contained
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        in this adapter.
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
280bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    public void sort(Comparator<? super T> comparator) {
281bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor        synchronized (mLock) {
282bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor            if (mOriginalValues != null) {
283bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor                Collections.sort(mOriginalValues, comparator);
284bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor            } else {
285bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor                Collections.sort(mObjects, comparator);
286bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor            }
287bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor        }
288bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor        if (mNotifyOnChange) notifyDataSetChanged();
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
290bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
292bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * {@inheritDoc}
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
294bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    @Override
2959b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li    public void notifyDataSetChanged() {
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.notifyDataSetChanged();
297bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor        mNotifyOnChange = true;
298bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    }
299bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
301bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * Control whether methods that change the list ({@link #add},
302bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * {@link #insert}, {@link #remove}, {@link #clear}) automatically call
303bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * {@link #notifyDataSetChanged}.  If set to false, caller must
304bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * manually call notifyDataSetChanged() to have the changes
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * reflected in the attached view.
306ffe1cf251a4f8469695b8acfa37270684dc1b70cWu-cheng Li     *
3079b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li     * The default is true, and calling notifyDataSetChanged()
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * resets the flag to true.
309bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     *
310bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * @param notifyOnChange if true, modifications to the list will
311bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     *                       automatically call {@link
312bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     *                       #notifyDataSetChanged}
313bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     */
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setNotifyOnChange(boolean notifyOnChange) {
315bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor        mNotifyOnChange = notifyOnChange;
316bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    }
317bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
318bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    /**
319bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * Returns the context associated with this array adapter. The context is used
320bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * to create views from the resource passed to the constructor.
321bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     *
322bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * @return The Context associated with this adapter.
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
324bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    public Context getContext() {
3259b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li        return mContext;
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
327bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
328fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis    /**
329fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis     * {@inheritDoc}
330fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis     */
331fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis    public int getCount() {
3329b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li        return mObjects.size();
333bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    }
334bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
335bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    /**
336bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * {@inheritDoc}
337bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     */
338bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    public T getItem(int position) {
339bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor        return mObjects.get(position);
340bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    }
341bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
342bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    /**
343bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * Returns the position of the specified item in the array.
344bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     *
345bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * @param item The item to retrieve the position of.
3469b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li     *
347bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * @return The position of the specified item.
348bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     */
349bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    public int getPosition(T item) {
350bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor        return mObjects.indexOf(item);
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
353b8a10fe45657f2dcc50cae8a06805f8438a6937eWu-cheng Li    /**
354b8a10fe45657f2dcc50cae8a06805f8438a6937eWu-cheng Li     * {@inheritDoc}
355b8a10fe45657f2dcc50cae8a06805f8438a6937eWu-cheng Li     */
356b8a10fe45657f2dcc50cae8a06805f8438a6937eWu-cheng Li    public long getItemId(int position) {
357b8a10fe45657f2dcc50cae8a06805f8438a6937eWu-cheng Li        return position;
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
360dbc289d6c27968bd05cc547ca73579347c3adc99Glenn Kasten    /**
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@inheritDoc}
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
363fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis    public View getView(int position, View convertView, ViewGroup parent) {
364fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis        return createViewFromResource(mInflater, position, convertView, parent, mResource);
365fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis    }
366fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis
367fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis    private View createViewFromResource(LayoutInflater inflater, int position, View convertView,
368fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis            ViewGroup parent, int resource) {
369fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis        View view;
370fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis        TextView text;
371fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis
372fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis        if (convertView == null) {
373fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis            view = inflater.inflate(resource, parent, false);
374fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis        } else {
375fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis            view = convertView;
376fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis        }
377fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis
378fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis        try {
379fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis            if (mFieldId == 0) {
380fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis                //  If no custom field is assigned, assume the whole resource is a TextView
381fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis                text = (TextView) view;
382fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis            } else {
383dbc289d6c27968bd05cc547ca73579347c3adc99Glenn Kasten                //  Otherwise, find the TextView field within the layout
384fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis                text = (TextView) view.findViewById(mFieldId);
385fd6f39e147dc077139a41b9c2a4039fbaa20224eJamie Gennis            }
386bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor        } catch (ClassCastException e) {
387bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor            Log.e("ArrayAdapter", "You must supply a resource ID for a TextView");
388bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor            throw new IllegalStateException(
389bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor                    "ArrayAdapter requires the resource ID to be a TextView", e);
390bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor        }
391bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
392bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor        T item = getItem(position);
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (item instanceof CharSequence) {
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            text.setText((CharSequence)item);
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            text.setText(item.toString());
397bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor        }
398341ff13689dfe822b598e626272ac2e80041b482Dan Egnor
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return view;
400bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    }
401a696f5d667227365da732481770767dcb330dd23Mathias Agopian
402df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main    /**
403da0a56df963353a1f1bd1914fa31f870d982dd5aScott Main     * <p>Sets the layout resource to create the drop down views.</p>
4049b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li     *
4059b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li     * @param resource the layout resource defining the drop down views
406bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * @see #getDropDownView(int, android.view.View, android.view.ViewGroup)
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setDropDownViewResource(int resource) {
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this.mDropDownResource = resource;
4109b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li    }
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
412bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    /**
413bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * Sets the {@link Resources.Theme} against which drop-down views are
414bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * inflated.
415bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * <p>
416bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * By default, drop-down views are inflated against the theme of the
417bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * {@link Context} passed to the adapter's constructor.
418bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     *
419bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * @param theme the theme against which to inflate drop-down views or
420bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     *              {@code null} to use the theme from the adapter's context
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getDropDownView(int, View, ViewGroup)
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4239b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li    @Override
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setDropDownViewTheme(Resources.Theme theme) {
425bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor        if (theme == null) {
426bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor            mDropDownInflater = null;
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (theme == mInflater.getContext().getTheme()) {
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDropDownInflater = mInflater;
4299b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li        } else {
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final Context context = new ContextThemeWrapper(mContext, theme);
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDropDownInflater = LayoutInflater.from(context);
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Resources.Theme getDropDownViewTheme() {
4379b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li        return mDropDownInflater == null ? null : mDropDownInflater.getContext().getTheme();
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
439bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
440bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    /**
441bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * {@inheritDoc}
442bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     */
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
444bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    public View getDropDownView(int position, View convertView, ViewGroup parent) {
445bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor        final LayoutInflater inflater = mDropDownInflater == null ? mInflater : mDropDownInflater;
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return createViewFromResource(inflater, position, convertView, parent, mDropDownResource);
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
45094927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp     * Creates a new ArrayAdapter from external resources. The content of the array is
451a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks     * obtained through {@link android.content.res.Resources#getTextArray(int)}.
452a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks     *
45394927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp     * @param context The application's environment.
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param textArrayResId The identifier of the array to use as the data source.
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param textViewResId The identifier of the layout used to create views.
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
457bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * @return An ArrayAdapter<CharSequence>.
458bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     */
459bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    public static ArrayAdapter<CharSequence> createFromResource(Context context,
460bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor            int textArrayResId, int textViewResId) {
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CharSequence[] strings = context.getResources().getTextArray(textArrayResId);
462bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor        return new ArrayAdapter<CharSequence>(context, textViewResId, strings);
463bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    }
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
46694927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp     * {@inheritDoc}
46794927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp     */
46894927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp    public Filter getFilter() {
46994927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp        if (mFilter == null) {
47094927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp            mFilter = new ArrayFilter();
47194927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp        }
47294927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp        return mFilter;
47394927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp    }
47494927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp
475bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor    /**
476bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * <p>An array filter constrains the content of the array adapter with
477bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * a prefix. Each item that does not start with the supplied prefix
478bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     * is removed from the list.</p>
479bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor     */
48094927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp    private class ArrayFilter extends Filter {
481bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor        @Override
482bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor        protected FilterResults performFiltering(CharSequence prefix) {
483bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor            FilterResults results = new FilterResults();
484bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
48594927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp            if (mOriginalValues == null) {
486bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor                synchronized (mLock) {
487bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor                    mOriginalValues = new ArrayList<T>(mObjects);
488bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor                }
48994927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp            }
490bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
491bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor            if (prefix == null || prefix.length() == 0) {
492bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor                ArrayList<T> list;
49394927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp                synchronized (mLock) {
49494927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp                    list = new ArrayList<T>(mOriginalValues);
49594927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp                }
49694927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp                results.values = list;
49794927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp                results.count = list.size();
49894927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp            } else {
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String prefixString = prefix.toString().toLowerCase();
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
50194927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp                ArrayList<T> values;
5023f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li                synchronized (mLock) {
5033f4639a6611222ae1ae5493de49213250d292139Wu-cheng Li                    values = new ArrayList<T>(mOriginalValues);
504bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor                }
505bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
506bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor                final int count = values.size();
507bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor                final ArrayList<T> newValues = new ArrayList<T>();
508bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
509c10275abd6a494c93a025f683dde104a5d4f2793Wu-cheng Li                for (int i = 0; i < count; i++) {
510bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor                    final T value = values.get(i);
511e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong                    final String valueText = value.toString().toLowerCase();
512e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong
513bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor                    // First match against the whole, non-splitted value
514bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor                    if (valueText.startsWith(prefixString)) {
515bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor                        newValues.add(value);
51694927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp                    } else {
517bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor                        final String[] words = valueText.split(" ");
518e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong                        final int wordCount = words.length;
519bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor
520bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor                        // Start at index 0, in case valueText starts with space(s)
521e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong                        for (int k = 0; k < wordCount; k++) {
522e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong                            if (words[k].startsWith(prefixString)) {
523e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong                                newValues.add(value);
52494927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp                                break;
525bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor                            }
526bfcbeffc54e93b1c2e2d95fdc301786df4376d6fDan Egnor                        }
5275b9bcda3a26e9b1f9b1eff28a2be8853d69614f0Wu-cheng Li                    }
52894927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp                }
529e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong
530e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong                results.values = newValues;
531e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong                results.count = newValues.size();
532e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong            }
533e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong
534e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong            return results;
535e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong        }
536e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong
537e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong        @Override
538e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong        protected void publishResults(CharSequence constraint, FilterResults results) {
539e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong            //noinspection unchecked
540e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong            mObjects = (List<T>) results.values;
541e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong            if (results.count > 0) {
542e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong                notifyDataSetChanged();
543e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong            } else {
544e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong                notifyDataSetInvalidated();
545e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong            }
546e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong        }
547e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong    }
548e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong}
549e00cab707dcaf6f05adb5ccb9c80fdf25c483427James Dong