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 197b9c912f536925ac6ec43935d6e97506851b33d6Tor Norbyeimport android.annotation.ArrayRes; 207b9c912f536925ac6ec43935d6e97506851b33d6Tor Norbyeimport android.annotation.IdRes; 217b9c912f536925ac6ec43935d6e97506851b33d6Tor Norbyeimport android.annotation.LayoutRes; 22417ee5ba89f7e0fe5efd34fce74bf1ee5923d976Tor Norbyeimport android.annotation.NonNull; 239e623b64b939944fa336264e2c8a555b817e4c2fAlan Viveretteimport android.annotation.Nullable; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 25b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viveretteimport android.content.res.Resources; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 27b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viveretteimport android.view.ContextThemeWrapper; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.LayoutInflater; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewGroup; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Arrays; 348c582ef859fcbbb97623d22024c3ecb32b65c5efChristian Mehlmauerimport java.util.Collection; 35c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Projectimport java.util.Collections; 36be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunneimport java.util.Comparator; 37be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunneimport java.util.List; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 40d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * You can use this adapter to provide views for an {@link AdapterView}, 41d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * Returns a view for each object in a collection of data objects you 42d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * provide, and can be used with list-based user interface widgets such as 43d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * {@link ListView} or {@link Spinner}. 44d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * <p> 45d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * By default, the array adapter creates a view by calling {@link Object#toString()} on each 46d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * data object in the collection you provide, and places the result in a TextView. 47d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * You may also customize what type of view is used for the data object in the collection. 48d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * To customize what type of view is used for the data object, 49d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * override {@link #getView(int, View, ViewGroup)} 50d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * and inflate a view resource. 51d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * For a code example, see 52d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * the <a href="https://developer.android.com/samples/CustomChoiceList/index.html"> 53d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * CustomChoiceList</a> sample. 54d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * </p> 55d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * <p> 56d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * For an example of using an array adapter with a ListView, see the 57d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * <a href="{@docRoot}guide/topics/ui/declaring-layout.html#AdapterViews"> 58d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * Adapter Views</a> guide. 59d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * </p> 60d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * <p> 61d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * For an example of using an array adapter with a Spinner, see the 62d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * <a href="{@docRoot}guide/topics/ui/controls/spinner.html">Spinners</a> guide. 63d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * </p> 64d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * <p class="note"><strong>Note:</strong> 65d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * If you are considering using array adapter with a ListView, consider using 66d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * {@link android.support.v7.widget.RecyclerView} instead. 67d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * RecyclerView offers similar features with better performance and more flexibility than 68d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * ListView provides. 69d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * See the 70d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * <a href="https://developer.android.com/guide/topics/ui/layout/recyclerview.html"> 71d7ef95af6069fcbd563aa9862a3d931e569cb54eJoe Fernandez * Recycler View</a> guide.</p> 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 732add9bcf8c33c59f300551bdb0671bbff0b55794Alan Viverettepublic class ArrayAdapter<T> extends BaseAdapter implements Filterable, ThemedSpinnerAdapter { 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Lock used to modify the content of {@link #mObjects}. Any write operation 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * performed on the array should be synchronized on this lock. This lock is also 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * used by the filter (see {@link #getFilter()} to make a synchronized copy of 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the original array of data. 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Object mLock = new Object(); 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 827d5967e55edc8c3dfdf72aea263b5543a2b6e801Alan Viverette private final LayoutInflater mInflater; 837d5967e55edc8c3dfdf72aea263b5543a2b6e801Alan Viverette 849e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette private final Context mContext; 857d5967e55edc8c3dfdf72aea263b5543a2b6e801Alan Viverette 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The resource indicating what views to inflate to display the content of this 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * array adapter. 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 909e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette private final int mResource; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The resource indicating what views to inflate to display the content of this 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * array adapter in a drop down widget. 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mDropDownResource; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 999e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette * Contains the list of objects that represent the data of this ArrayAdapter. 1009e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette * The content of this list is referred to as "the array" in the documentation. 1019e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette */ 1029e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette private List<T> mObjects; 1039e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette 1049e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette /** 1057e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme * Indicates whether the contents of {@link #mObjects} came from static resources. 1067e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme */ 1077e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme private boolean mObjectsFromResources; 1087e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme 1097e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme /** 1109e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette * If the inflated resource is not a TextView, {@code mFieldId} is used to find 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a TextView inside the inflated views hierarchy. This field must contain the 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * identifier that matches the one defined in the resource file. 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mFieldId = 0; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Indicates whether or not {@link #notifyDataSetChanged()} must be called whenever 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #mObjects} is modified. 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mNotifyOnChange = true; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 122be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne // A copy of the original mObjects array, initialized from and then used instead as soon as 123be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne // the mFilter ArrayFilter is used. mObjects will then only contain the filtered values. 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ArrayList<T> mOriginalValues; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ArrayFilter mFilter; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 127b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette /** Layout inflater used for {@link #getDropDownView(int, View, ViewGroup)}. */ 128b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette private LayoutInflater mDropDownInflater; 129b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Constructor 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context The current context. 1349c5d1b17bfae81c282cec8954e66963c86c81438Romain Guy * @param resource The resource ID for a layout file containing a TextView to use when 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * instantiating views. 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1379e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette public ArrayAdapter(@NonNull Context context, @LayoutRes int resource) { 1389e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette this(context, resource, 0, new ArrayList<>()); 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Constructor 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context The current context. 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param resource The resource ID for a layout file containing a layout to use when 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * instantiating views. 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param textViewResourceId The id of the TextView within the layout resource to be populated 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1499e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette public ArrayAdapter(@NonNull Context context, @LayoutRes int resource, 1509e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette @IdRes int textViewResourceId) { 1519e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette this(context, resource, textViewResourceId, new ArrayList<>()); 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Constructor 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context The current context. 1589c5d1b17bfae81c282cec8954e66963c86c81438Romain Guy * @param resource The resource ID for a layout file containing a TextView to use when 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * instantiating views. 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param objects The objects to represent in the ListView. 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1629e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette public ArrayAdapter(@NonNull Context context, @LayoutRes int resource, @NonNull T[] objects) { 163b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette this(context, resource, 0, Arrays.asList(objects)); 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Constructor 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context The current context. 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param resource The resource ID for a layout file containing a layout to use when 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * instantiating views. 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param textViewResourceId The id of the TextView within the layout resource to be populated 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param objects The objects to represent in the ListView. 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1759e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette public ArrayAdapter(@NonNull Context context, @LayoutRes int resource, 1769e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette @IdRes int textViewResourceId, @NonNull T[] objects) { 177b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette this(context, resource, textViewResourceId, Arrays.asList(objects)); 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Constructor 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context The current context. 1849c5d1b17bfae81c282cec8954e66963c86c81438Romain Guy * @param resource The resource ID for a layout file containing a TextView to use when 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * instantiating views. 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param objects The objects to represent in the ListView. 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1889e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette public ArrayAdapter(@NonNull Context context, @LayoutRes int resource, 1899e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette @NonNull List<T> objects) { 190b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette this(context, resource, 0, objects); 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Constructor 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context The current context. 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param resource The resource ID for a layout file containing a layout to use when 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * instantiating views. 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param textViewResourceId The id of the TextView within the layout resource to be populated 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param objects The objects to represent in the ListView. 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2029e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette public ArrayAdapter(@NonNull Context context, @LayoutRes int resource, 2039e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette @IdRes int textViewResourceId, @NonNull List<T> objects) { 2047e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme this(context, resource, textViewResourceId, objects, false); 2057e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme } 2067e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme 2077e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme private ArrayAdapter(@NonNull Context context, @LayoutRes int resource, 2087e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme @IdRes int textViewResourceId, @NonNull List<T> objects, boolean objsFromResources) { 209b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette mContext = context; 210b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette mInflater = LayoutInflater.from(context); 211b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette mResource = mDropDownResource = resource; 212b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette mObjects = objects; 2137e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme mObjectsFromResources = objsFromResources; 214b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette mFieldId = textViewResourceId; 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Adds the specified object at the end of the array. 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param object The object to add at the end of the array. 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2229e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette public void add(@Nullable T object) { 223be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne synchronized (mLock) { 224be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne if (mOriginalValues != null) { 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOriginalValues.add(object); 226be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne } else { 227be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne mObjects.add(object); 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2297e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme mObjectsFromResources = false; 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 231be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne if (mNotifyOnChange) notifyDataSetChanged(); 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2358c582ef859fcbbb97623d22024c3ecb32b65c5efChristian Mehlmauer * Adds the specified Collection at the end of the array. 2368c582ef859fcbbb97623d22024c3ecb32b65c5efChristian Mehlmauer * 2378c582ef859fcbbb97623d22024c3ecb32b65c5efChristian Mehlmauer * @param collection The Collection to add at the end of the array. 2389e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette * @throws UnsupportedOperationException if the <tt>addAll</tt> operation 2399e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette * is not supported by this list 2409e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette * @throws ClassCastException if the class of an element of the specified 2419e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette * collection prevents it from being added to this list 2429e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette * @throws NullPointerException if the specified collection contains one 2439e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette * or more null elements and this list does not permit null 2449e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette * elements, or if the specified collection is null 2459e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette * @throws IllegalArgumentException if some property of an element of the 2469e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette * specified collection prevents it from being added to this list 2479e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette */ 2489e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette public void addAll(@NonNull Collection<? extends T> collection) { 249be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne synchronized (mLock) { 250be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne if (mOriginalValues != null) { 2518c582ef859fcbbb97623d22024c3ecb32b65c5efChristian Mehlmauer mOriginalValues.addAll(collection); 252be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne } else { 253be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne mObjects.addAll(collection); 2548c582ef859fcbbb97623d22024c3ecb32b65c5efChristian Mehlmauer } 2557e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme mObjectsFromResources = false; 2568c582ef859fcbbb97623d22024c3ecb32b65c5efChristian Mehlmauer } 257be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne if (mNotifyOnChange) notifyDataSetChanged(); 2588c582ef859fcbbb97623d22024c3ecb32b65c5efChristian Mehlmauer } 2598c582ef859fcbbb97623d22024c3ecb32b65c5efChristian Mehlmauer 2608c582ef859fcbbb97623d22024c3ecb32b65c5efChristian Mehlmauer /** 2618c582ef859fcbbb97623d22024c3ecb32b65c5efChristian Mehlmauer * Adds the specified items at the end of the array. 2628c582ef859fcbbb97623d22024c3ecb32b65c5efChristian Mehlmauer * 2638c582ef859fcbbb97623d22024c3ecb32b65c5efChristian Mehlmauer * @param items The items to add at the end of the array. 2648c582ef859fcbbb97623d22024c3ecb32b65c5efChristian Mehlmauer */ 2658c582ef859fcbbb97623d22024c3ecb32b65c5efChristian Mehlmauer public void addAll(T ... items) { 266be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne synchronized (mLock) { 267be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne if (mOriginalValues != null) { 26895a78c38373bb99258d83a6ab2c92825d979f200Romain Guy Collections.addAll(mOriginalValues, items); 269be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne } else { 27095a78c38373bb99258d83a6ab2c92825d979f200Romain Guy Collections.addAll(mObjects, items); 2718c582ef859fcbbb97623d22024c3ecb32b65c5efChristian Mehlmauer } 2727e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme mObjectsFromResources = false; 2738c582ef859fcbbb97623d22024c3ecb32b65c5efChristian Mehlmauer } 274be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne if (mNotifyOnChange) notifyDataSetChanged(); 2758c582ef859fcbbb97623d22024c3ecb32b65c5efChristian Mehlmauer } 2768c582ef859fcbbb97623d22024c3ecb32b65c5efChristian Mehlmauer 2778c582ef859fcbbb97623d22024c3ecb32b65c5efChristian Mehlmauer /** 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inserts the specified object at the specified index in the array. 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param object The object to insert into the array. 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param index The index at which the object must be inserted. 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2839e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette public void insert(@Nullable T object, int index) { 284be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne synchronized (mLock) { 285be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne if (mOriginalValues != null) { 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOriginalValues.add(index, object); 287be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne } else { 288be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne mObjects.add(index, object); 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2907e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme mObjectsFromResources = false; 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 292be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne if (mNotifyOnChange) notifyDataSetChanged(); 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Removes the specified object from the array. 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param object The object to remove. 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3009e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette public void remove(@Nullable T object) { 301be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne synchronized (mLock) { 302be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne if (mOriginalValues != null) { 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOriginalValues.remove(object); 304be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne } else { 305be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne mObjects.remove(object); 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3077e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme mObjectsFromResources = false; 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNotifyOnChange) notifyDataSetChanged(); 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Remove all elements from the list. 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void clear() { 316be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne synchronized (mLock) { 317be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne if (mOriginalValues != null) { 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOriginalValues.clear(); 319be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne } else { 320be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne mObjects.clear(); 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3227e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme mObjectsFromResources = false; 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNotifyOnChange) notifyDataSetChanged(); 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 328c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * Sorts the content of this adapter using the specified comparator. 329c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * 330c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * @param comparator The comparator used to sort the objects contained 331c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * in this adapter. 332c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project */ 3339e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette public void sort(@NonNull Comparator<? super T> comparator) { 334be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne synchronized (mLock) { 335be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne if (mOriginalValues != null) { 336be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne Collections.sort(mOriginalValues, comparator); 337be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne } else { 338be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne Collections.sort(mObjects, comparator); 339be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne } 340be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne } 3418c582ef859fcbbb97623d22024c3ecb32b65c5efChristian Mehlmauer if (mNotifyOnChange) notifyDataSetChanged(); 342c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project } 343c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void notifyDataSetChanged() { 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.notifyDataSetChanged(); 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNotifyOnChange = true; 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 35142c69b9ce4ead51fc5e2a0ed55c40b498893047eYigit Boyar * Control whether methods that change the list ({@link #add}, {@link #addAll(Collection)}, 35242c69b9ce4ead51fc5e2a0ed55c40b498893047eYigit Boyar * {@link #addAll(Object[])}, {@link #insert}, {@link #remove}, {@link #clear}, 35342c69b9ce4ead51fc5e2a0ed55c40b498893047eYigit Boyar * {@link #sort(Comparator)}) automatically call {@link #notifyDataSetChanged}. If set to 35442c69b9ce4ead51fc5e2a0ed55c40b498893047eYigit Boyar * false, caller must manually call notifyDataSetChanged() to have the changes 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * reflected in the attached view. 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default is true, and calling notifyDataSetChanged() 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * resets the flag to true. 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param notifyOnChange if true, modifications to the list will 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * automatically call {@link 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * #notifyDataSetChanged} 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setNotifyOnChange(boolean notifyOnChange) { 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNotifyOnChange = notifyOnChange; 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the context associated with this array adapter. The context is used 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to create views from the resource passed to the constructor. 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The Context associated with this adapter. 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3749e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette public @NonNull Context getContext() { 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mContext; 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3789e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette @Override 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getCount() { 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mObjects.size(); 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3839e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette @Override 3849e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette public @Nullable T getItem(int position) { 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mObjects.get(position); 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the position of the specified item in the array. 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param item The item to retrieve the position of. 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The position of the specified item. 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3959e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette public int getPosition(@Nullable T item) { 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mObjects.indexOf(item); 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3999e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette @Override 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long getItemId(int position) { 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return position; 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4049e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette @Override 4059e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette public @NonNull View getView(int position, @Nullable View convertView, 4069e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette @NonNull ViewGroup parent) { 407b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette return createViewFromResource(mInflater, position, convertView, parent, mResource); 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4109e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette private @NonNull View createViewFromResource(@NonNull LayoutInflater inflater, int position, 4119e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette @Nullable View convertView, @NonNull ViewGroup parent, int resource) { 4129e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette final View view; 4139e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette final TextView text; 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (convertView == null) { 416b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette view = inflater.inflate(resource, parent, false); 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project view = convertView; 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFieldId == 0) { 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If no custom field is assigned, assume the whole resource is a TextView 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project text = (TextView) view; 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Otherwise, find the TextView field within the layout 4278e1a72964517bfd01d8e650453ef41e22f770f21Alan Viverette text = view.findViewById(mFieldId); 4289e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette 4299e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette if (text == null) { 4309e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette throw new RuntimeException("Failed to find view with ID " 4319e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette + mContext.getResources().getResourceName(mFieldId) 4329e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette + " in item layout"); 4339e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette } 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (ClassCastException e) { 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e("ArrayAdapter", "You must supply a resource ID for a TextView"); 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalStateException( 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "ArrayAdapter requires the resource ID to be a TextView", e); 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4419e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette final T item = getItem(position); 442b5d9132d4eaeed13b236501e4af3f99416b4be78Daisuke Miyakawa if (item instanceof CharSequence) { 4439e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette text.setText((CharSequence) item); 444b5d9132d4eaeed13b236501e4af3f99416b4be78Daisuke Miyakawa } else { 445b5d9132d4eaeed13b236501e4af3f99416b4be78Daisuke Miyakawa text.setText(item.toString()); 446b5d9132d4eaeed13b236501e4af3f99416b4be78Daisuke Miyakawa } 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return view; 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Sets the layout resource to create the drop down views.</p> 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param resource the layout resource defining the drop down views 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getDropDownView(int, android.view.View, android.view.ViewGroup) 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4577b9c912f536925ac6ec43935d6e97506851b33d6Tor Norbye public void setDropDownViewResource(@LayoutRes int resource) { 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.mDropDownResource = resource; 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 462b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette * Sets the {@link Resources.Theme} against which drop-down views are 463b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette * inflated. 464b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette * <p> 465b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette * By default, drop-down views are inflated against the theme of the 466b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette * {@link Context} passed to the adapter's constructor. 467b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette * 468b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette * @param theme the theme against which to inflate drop-down views or 469b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette * {@code null} to use the theme from the adapter's context 470b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette * @see #getDropDownView(int, View, ViewGroup) 471b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette */ 472b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette @Override 4739e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette public void setDropDownViewTheme(@Nullable Resources.Theme theme) { 474b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette if (theme == null) { 475b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette mDropDownInflater = null; 476b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette } else if (theme == mInflater.getContext().getTheme()) { 477b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette mDropDownInflater = mInflater; 478b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette } else { 479b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette final Context context = new ContextThemeWrapper(mContext, theme); 480b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette mDropDownInflater = LayoutInflater.from(context); 481b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette } 482b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette } 483b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette 484b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette @Override 4859e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette public @Nullable Resources.Theme getDropDownViewTheme() { 486b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette return mDropDownInflater == null ? null : mDropDownInflater.getContext().getTheme(); 487b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette } 488b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4909e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette public View getDropDownView(int position, @Nullable View convertView, 4919e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette @NonNull ViewGroup parent) { 492b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette final LayoutInflater inflater = mDropDownInflater == null ? mInflater : mDropDownInflater; 493b9ead4a91599ca63e947f74f83b67a58bda64a82Alan Viverette return createViewFromResource(inflater, position, convertView, parent, mDropDownResource); 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creates a new ArrayAdapter from external resources. The content of the array is 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * obtained through {@link android.content.res.Resources#getTextArray(int)}. 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context The application's environment. 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param textArrayResId The identifier of the array to use as the data source. 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param textViewResId The identifier of the layout used to create views. 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return An ArrayAdapter<CharSequence>. 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5069e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette public static @NonNull ArrayAdapter<CharSequence> createFromResource(@NonNull Context context, 5077b9c912f536925ac6ec43935d6e97506851b33d6Tor Norbye @ArrayRes int textArrayResId, @LayoutRes int textViewResId) { 5089e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette final CharSequence[] strings = context.getResources().getTextArray(textArrayResId); 5097e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme return new ArrayAdapter<>(context, textViewResId, 0, Arrays.asList(strings), true); 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5129e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette @Override 5139e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette public @NonNull Filter getFilter() { 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFilter == null) { 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFilter = new ArrayFilter(); 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFilter; 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5217e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme * {@inheritDoc} 5227e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme * 5237e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme * @return values from the string array used by {@link #createFromResource(Context, int, int)}, 5247e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme * or {@code null} if object was created otherwsie or if contents were dynamically changed after 5257e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme * creation. 5267e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme */ 5277e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme @Override 5287e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme public CharSequence[] getAutofillOptions() { 5297e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme if (!mObjectsFromResources || mObjects == null || mObjects.isEmpty()) { 5307e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme return null; 5317e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme } 5327e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme final int size = mObjects.size(); 5337e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme final CharSequence[] options = new CharSequence[size]; 5347e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme mObjects.toArray(options); 5357e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme return options; 5367e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme } 5377e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme 5387e4c205d8f7e6746ab6e0701e4d7776a2cdd6aa0Felipe Leme /** 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>An array filter constrains the content of the array adapter with 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a prefix. Each item that does not start with the supplied prefix 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is removed from the list.</p> 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class ArrayFilter extends Filter { 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected FilterResults performFiltering(CharSequence prefix) { 5469e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette final FilterResults results = new FilterResults(); 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOriginalValues == null) { 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 5509e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette mOriginalValues = new ArrayList<>(mObjects); 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (prefix == null || prefix.length() == 0) { 5559e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette final ArrayList<T> list; 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 5579e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette list = new ArrayList<>(mOriginalValues); 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 55995a78c38373bb99258d83a6ab2c92825d979f200Romain Guy results.values = list; 56095a78c38373bb99258d83a6ab2c92825d979f200Romain Guy results.count = list.size(); 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5629e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette final String prefixString = prefix.toString().toLowerCase(); 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5649e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette final ArrayList<T> values; 56595a78c38373bb99258d83a6ab2c92825d979f200Romain Guy synchronized (mLock) { 5669e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette values = new ArrayList<>(mOriginalValues); 56795a78c38373bb99258d83a6ab2c92825d979f200Romain Guy } 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 56995a78c38373bb99258d83a6ab2c92825d979f200Romain Guy final int count = values.size(); 5709e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette final ArrayList<T> newValues = new ArrayList<>(); 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < count; i++) { 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final T value = values.get(i); 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final String valueText = value.toString().toLowerCase(); 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // First match against the whole, non-splitted value 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (valueText.startsWith(prefixString)) { 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newValues.add(value); 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final String[] words = valueText.split(" "); 5819e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette for (String word : words) { 5829e623b64b939944fa336264e2c8a555b817e4c2fAlan Viverette if (word.startsWith(prefixString)) { 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newValues.add(value); 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project results.values = newValues; 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project results.count = newValues.size(); 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return results; 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void publishResults(CharSequence constraint, FilterResults results) { 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //noinspection unchecked 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mObjects = (List<T>) results.values; 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (results.count > 0) { 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyDataSetChanged(); 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyDataSetInvalidated(); 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 609