19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 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.preference; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Collections; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2335d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglioimport android.graphics.drawable.Drawable; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.preference.Preference.OnPreferenceChangeInternalListener; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewGroup; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.widget.Adapter; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.widget.BaseAdapter; 305f9f6c3936a8a266bb5dcd31e94d403917f1bbe8Fabrice Di Meglioimport android.widget.FrameLayout; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.widget.ListView; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * An adapter that returns the {@link Preference} contained in this group. 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * In most cases, this adapter should be the base class for any custom 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * adapters from {@link Preference#getAdapter()}. 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This adapter obeys the 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link Preference}'s adapter rule (the 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link Adapter#getView(int, View, ViewGroup)} should be used instead of 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link Preference#getView(ViewGroup)} if a {@link Preference} has an 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * adapter via {@link Preference#getAdapter()}). 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This adapter also propagates data change/invalidated notifications upward. 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This adapter does not include this {@link PreferenceGroup} in the returned 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * adapter, use {@link PreferenceCategoryAdapter} instead. 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see PreferenceCategoryAdapter 5053c2cf799fddfae7f6fc9ca1840ea345308b79eeFabrice Di Meglio * 5153c2cf799fddfae7f6fc9ca1840ea345308b79eeFabrice Di Meglio * @hide 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5353c2cf799fddfae7f6fc9ca1840ea345308b79eeFabrice Di Megliopublic class PreferenceGroupAdapter extends BaseAdapter 5453c2cf799fddfae7f6fc9ca1840ea345308b79eeFabrice Di Meglio implements OnPreferenceChangeInternalListener { 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "PreferenceGroupAdapter"; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The group that we are providing data from. 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private PreferenceGroup mPreferenceGroup; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Maps a position into this adapter -> {@link Preference}. These 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link Preference}s don't have to be direct children of this 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link PreferenceGroup}, they can be grand children or younger) 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private List<Preference> mPreferenceList; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * List of unique Preference and its subclasses' names. This is used to find 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * out how many types of views this adapter can return. Once the count is 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * returned, this cannot be modified (since the ListView only checks the 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * count once--when the adapter is being set). We will not recycle views for 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Preference subclasses seen after the count has been returned. 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 77a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani private ArrayList<PreferenceLayout> mPreferenceLayouts; 78a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani 79a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani private PreferenceLayout mTempPreferenceLayout = new PreferenceLayout(); 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Blocks the mPreferenceClassNames from being changed anymore. 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mHasReturnedViewTypeCount = false; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private volatile boolean mIsSyncing = false; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Handler mHandler = new Handler(); 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Runnable mSyncRunnable = new Runnable() { 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project syncMyPreferences(); 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9635d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio private int mHighlightedPosition = -1; 9735d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio private Drawable mHighlightedDrawable; 9853c2cf799fddfae7f6fc9ca1840ea345308b79eeFabrice Di Meglio 995f9f6c3936a8a266bb5dcd31e94d403917f1bbe8Fabrice Di Meglio private static ViewGroup.LayoutParams sWrapperLayoutParams = new ViewGroup.LayoutParams( 1005f9f6c3936a8a266bb5dcd31e94d403917f1bbe8Fabrice Di Meglio ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); 1015f9f6c3936a8a266bb5dcd31e94d403917f1bbe8Fabrice Di Meglio 102a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani private static class PreferenceLayout implements Comparable<PreferenceLayout> { 103a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani private int resId; 104a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani private int widgetResId; 105a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani private String name; 106a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani 107a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani public int compareTo(PreferenceLayout other) { 108a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani int compareNames = name.compareTo(other.name); 109a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani if (compareNames == 0) { 110a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani if (resId == other.resId) { 111a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani if (widgetResId == other.widgetResId) { 112a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani return 0; 113a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani } else { 114a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani return widgetResId - other.widgetResId; 115a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani } 116a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani } else { 117a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani return resId - other.resId; 118a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani } 119a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani } else { 120a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani return compareNames; 121a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani } 122a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani } 123a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani } 124a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PreferenceGroupAdapter(PreferenceGroup preferenceGroup) { 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPreferenceGroup = preferenceGroup; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If this group gets or loses any children, let us know 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPreferenceGroup.setOnPreferenceChangeInternalListener(this); 129a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPreferenceList = new ArrayList<Preference>(); 131a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani mPreferenceLayouts = new ArrayList<PreferenceLayout>(); 132a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project syncMyPreferences(); 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void syncMyPreferences() { 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(this) { 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsSyncing) { 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 141a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsSyncing = true; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<Preference> newPreferenceList = new ArrayList<Preference>(mPreferenceList.size()); 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flattenPreferenceGroup(newPreferenceList, mPreferenceGroup); 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPreferenceList = newPreferenceList; 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyDataSetChanged(); 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(this) { 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsSyncing = false; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyAll(); 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void flattenPreferenceGroup(List<Preference> preferences, PreferenceGroup group) { 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: shouldn't always? 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project group.sortPreferences(); 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int groupSize = group.getPreferenceCount(); 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < groupSize; i++) { 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Preference preference = group.getPreference(i); 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project preferences.add(preference); 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1674186b344d829e155feebf6797bd41576fccb5f16Filip Pavlis if (!mHasReturnedViewTypeCount && preference.isRecycleEnabled()) { 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addPreferenceClassName(preference); 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (preference instanceof PreferenceGroup) { 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final PreferenceGroup preferenceAsGroup = (PreferenceGroup) preference; 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (preferenceAsGroup.isOnSameScreenAsChildren()) { 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flattenPreferenceGroup(preferences, preferenceAsGroup); 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project preference.setOnPreferenceChangeInternalListener(this); 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 182a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani /** 183a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani * Creates a string that includes the preference name, layout id and widget layout id. 184a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani * If a particular preference type uses 2 different resources, they will be treated as 185a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani * different view types. 186a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani */ 187a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani private PreferenceLayout createPreferenceLayout(Preference preference, PreferenceLayout in) { 188a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani PreferenceLayout pl = in != null? in : new PreferenceLayout(); 189a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani pl.name = preference.getClass().getName(); 190a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani pl.resId = preference.getLayoutResource(); 191a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani pl.widgetResId = preference.getWidgetLayoutResource(); 192a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani return pl; 193a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani } 194a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void addPreferenceClassName(Preference preference) { 196a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani final PreferenceLayout pl = createPreferenceLayout(preference, null); 197a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani int insertPos = Collections.binarySearch(mPreferenceLayouts, pl); 198a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Only insert if it doesn't exist (when it is negative). 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (insertPos < 0) { 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Convert to insert index 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project insertPos = insertPos * -1 - 1; 203a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani mPreferenceLayouts.add(insertPos, pl); 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getCount() { 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mPreferenceList.size(); 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Preference getItem(int position) { 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (position < 0 || position >= getCount()) return null; 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mPreferenceList.get(position); 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long getItemId(int position) { 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (position < 0 || position >= getCount()) return ListView.INVALID_ROW_ID; 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return this.getItem(position).getId(); 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22135d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio /** 22235d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio * @hide 22335d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio */ 22435d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio public void setHighlighted(int position) { 22535d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio mHighlightedPosition = position; 22635d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio } 22735d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio 22835d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio /** 22935d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio * @hide 23035d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio */ 23135d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio public void setHighlightedDrawable(Drawable drawable) { 23235d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio mHighlightedDrawable = drawable; 23353c2cf799fddfae7f6fc9ca1840ea345308b79eeFabrice Di Meglio } 23453c2cf799fddfae7f6fc9ca1840ea345308b79eeFabrice Di Meglio 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public View getView(int position, View convertView, ViewGroup parent) { 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Preference preference = this.getItem(position); 237a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani // Build a PreferenceLayout to compare with known ones that are cacheable. 238a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani mTempPreferenceLayout = createPreferenceLayout(preference, mTempPreferenceLayout); 239a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani 240a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani // If it's not one of the cached ones, set the convertView to null so that 241a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani // the layout gets re-created by the Preference. 2425f9f6c3936a8a266bb5dcd31e94d403917f1bbe8Fabrice Di Meglio if (Collections.binarySearch(mPreferenceLayouts, mTempPreferenceLayout) < 0 || 2435f9f6c3936a8a266bb5dcd31e94d403917f1bbe8Fabrice Di Meglio (getItemViewType(position) == getHighlightItemViewType())) { 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project convertView = null; 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24653c2cf799fddfae7f6fc9ca1840ea345308b79eeFabrice Di Meglio View result = preference.getView(convertView, parent); 24735d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio if (position == mHighlightedPosition && mHighlightedDrawable != null) { 2485f9f6c3936a8a266bb5dcd31e94d403917f1bbe8Fabrice Di Meglio ViewGroup wrapper = new FrameLayout(parent.getContext()); 2495f9f6c3936a8a266bb5dcd31e94d403917f1bbe8Fabrice Di Meglio wrapper.setLayoutParams(sWrapperLayoutParams); 2505f9f6c3936a8a266bb5dcd31e94d403917f1bbe8Fabrice Di Meglio wrapper.setBackgroundDrawable(mHighlightedDrawable); 2515f9f6c3936a8a266bb5dcd31e94d403917f1bbe8Fabrice Di Meglio wrapper.addView(result); 2525f9f6c3936a8a266bb5dcd31e94d403917f1bbe8Fabrice Di Meglio result = wrapper; 25335d7b89b9f6151083001e3bae315a8e98882741fFabrice Di Meglio } 25453c2cf799fddfae7f6fc9ca1840ea345308b79eeFabrice Di Meglio return result; 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isEnabled(int position) { 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (position < 0 || position >= getCount()) return true; 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return this.getItem(position).isSelectable(); 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean areAllItemsEnabled() { 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // There should always be a preference group, and these groups are always 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // disabled 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onPreferenceChange(Preference preference) { 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyDataSetChanged(); 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onPreferenceHierarchyChange(Preference preference) { 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.removeCallbacks(mSyncRunnable); 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.post(mSyncRunnable); 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean hasStableIds() { 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2845f9f6c3936a8a266bb5dcd31e94d403917f1bbe8Fabrice Di Meglio private int getHighlightItemViewType() { 2855f9f6c3936a8a266bb5dcd31e94d403917f1bbe8Fabrice Di Meglio return getViewTypeCount() - 1; 2865f9f6c3936a8a266bb5dcd31e94d403917f1bbe8Fabrice Di Meglio } 2875f9f6c3936a8a266bb5dcd31e94d403917f1bbe8Fabrice Di Meglio 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getItemViewType(int position) { 2905f9f6c3936a8a266bb5dcd31e94d403917f1bbe8Fabrice Di Meglio if (position == mHighlightedPosition) { 2915f9f6c3936a8a266bb5dcd31e94d403917f1bbe8Fabrice Di Meglio return getHighlightItemViewType(); 2925f9f6c3936a8a266bb5dcd31e94d403917f1bbe8Fabrice Di Meglio } 2935f9f6c3936a8a266bb5dcd31e94d403917f1bbe8Fabrice Di Meglio 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mHasReturnedViewTypeCount) { 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHasReturnedViewTypeCount = true; 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Preference preference = this.getItem(position); 2994186b344d829e155feebf6797bd41576fccb5f16Filip Pavlis if (!preference.isRecycleEnabled()) { 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return IGNORE_ITEM_VIEW_TYPE; 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 303a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani mTempPreferenceLayout = createPreferenceLayout(preference, mTempPreferenceLayout); 304a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani 305a98129b9110371aa036d8fcf23fff709595b16ffAmith Yamasani int viewType = Collections.binarySearch(mPreferenceLayouts, mTempPreferenceLayout); 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (viewType < 0) { 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is a class that was seen after we returned the count, so 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // don't recycle it. 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return IGNORE_ITEM_VIEW_TYPE; 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return viewType; 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getViewTypeCount() { 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mHasReturnedViewTypeCount) { 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHasReturnedViewTypeCount = true; 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3215f9f6c3936a8a266bb5dcd31e94d403917f1bbe8Fabrice Di Meglio return Math.max(1, mPreferenceLayouts.size()) + 1; 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 325