diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/preference/Preference.java | 27 | ||||
-rw-r--r-- | core/java/android/preference/PreferenceGroupAdapter.java | 83 |
2 files changed, 72 insertions, 38 deletions
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java index 08a2a9f..197d976 100644 --- a/core/java/android/preference/Preference.java +++ b/core/java/android/preference/Preference.java @@ -188,17 +188,7 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis mContext = context; TypedArray a = context.obtainStyledAttributes(attrs, - com.android.internal.R.styleable.Preference); - if (a.hasValue(com.android.internal.R.styleable.Preference_layout) || - a.hasValue(com.android.internal.R.styleable.Preference_widgetLayout)) { - // This preference has a custom layout defined (not one taken from - // the default style) - mHasSpecifiedLayout = true; - } - a.recycle(); - - a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.Preference, - defStyle, 0); + com.android.internal.R.styleable.Preference, defStyle, 0); for (int i = a.getIndexCount(); i >= 0; i--) { int attr = a.getIndex(i); switch (attr) { @@ -252,6 +242,11 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis } } a.recycle(); + + if (!getClass().getName().startsWith("android.preference")) { + // For subclasses not in this package, assume the worst and don't cache views + mHasSpecifiedLayout = true; + } } /** @@ -332,11 +327,11 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis * @see #setWidgetLayoutResource(int) */ public void setLayoutResource(int layoutResId) { - - if (!mHasSpecifiedLayout) { + if (layoutResId != mLayoutResId) { + // Layout changed mHasSpecifiedLayout = true; } - + mLayoutResId = layoutResId; } @@ -360,6 +355,10 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis * @see #setLayoutResource(int) */ public void setWidgetLayoutResource(int widgetLayoutResId) { + if (widgetLayoutResId != mWidgetLayoutResId) { + // Layout changed + mHasSpecifiedLayout = true; + } mWidgetLayoutResId = widgetLayoutResId; } diff --git a/core/java/android/preference/PreferenceGroupAdapter.java b/core/java/android/preference/PreferenceGroupAdapter.java index 14c0054..a908ecd 100644 --- a/core/java/android/preference/PreferenceGroupAdapter.java +++ b/core/java/android/preference/PreferenceGroupAdapter.java @@ -69,7 +69,9 @@ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeIn * count once--when the adapter is being set). We will not recycle views for * Preference subclasses seen after the count has been returned. */ - private List<String> mPreferenceClassNames; + private ArrayList<PreferenceLayout> mPreferenceLayouts; + + private PreferenceLayout mTempPreferenceLayout = new PreferenceLayout(); /** * Blocks the mPreferenceClassNames from being changed anymore. @@ -86,14 +88,37 @@ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeIn } }; + private static class PreferenceLayout implements Comparable<PreferenceLayout> { + private int resId; + private int widgetResId; + private String name; + + public int compareTo(PreferenceLayout other) { + int compareNames = name.compareTo(other.name); + if (compareNames == 0) { + if (resId == other.resId) { + if (widgetResId == other.widgetResId) { + return 0; + } else { + return widgetResId - other.widgetResId; + } + } else { + return resId - other.resId; + } + } else { + return compareNames; + } + } + } + public PreferenceGroupAdapter(PreferenceGroup preferenceGroup) { mPreferenceGroup = preferenceGroup; // If this group gets or loses any children, let us know mPreferenceGroup.setOnPreferenceChangeInternalListener(this); - + mPreferenceList = new ArrayList<Preference>(); - mPreferenceClassNames = new ArrayList<String>(); - + mPreferenceLayouts = new ArrayList<PreferenceLayout>(); + syncMyPreferences(); } @@ -102,7 +127,7 @@ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeIn if (mIsSyncing) { return; } - + mIsSyncing = true; } @@ -128,7 +153,7 @@ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeIn preferences.add(preference); - if (!mHasReturnedViewTypeCount) { + if (!mHasReturnedViewTypeCount && !preference.hasSpecifiedLayout()) { addPreferenceClassName(preference); } @@ -143,15 +168,28 @@ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeIn } } + /** + * Creates a string that includes the preference name, layout id and widget layout id. + * If a particular preference type uses 2 different resources, they will be treated as + * different view types. + */ + private PreferenceLayout createPreferenceLayout(Preference preference, PreferenceLayout in) { + PreferenceLayout pl = in != null? in : new PreferenceLayout(); + pl.name = preference.getClass().getName(); + pl.resId = preference.getLayoutResource(); + pl.widgetResId = preference.getWidgetLayoutResource(); + return pl; + } + private void addPreferenceClassName(Preference preference) { - final String name = preference.getClass().getName(); - int insertPos = Collections.binarySearch(mPreferenceClassNames, name); - + final PreferenceLayout pl = createPreferenceLayout(preference, null); + int insertPos = Collections.binarySearch(mPreferenceLayouts, pl); + // Only insert if it doesn't exist (when it is negative). if (insertPos < 0) { // Convert to insert index insertPos = insertPos * -1 - 1; - mPreferenceClassNames.add(insertPos, name); + mPreferenceLayouts.add(insertPos, pl); } } @@ -171,19 +209,15 @@ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeIn public View getView(int position, View convertView, ViewGroup parent) { final Preference preference = this.getItem(position); - - if (preference.hasSpecifiedLayout()) { - // If the preference had specified a layout (as opposed to the - // default), don't use convert views. + // Build a PreferenceLayout to compare with known ones that are cacheable. + mTempPreferenceLayout = createPreferenceLayout(preference, mTempPreferenceLayout); + + // If it's not one of the cached ones, set the convertView to null so that + // the layout gets re-created by the Preference. + if (Collections.binarySearch(mPreferenceLayouts, mTempPreferenceLayout) < 0) { convertView = null; - } else { - // TODO: better way of doing this - final String name = preference.getClass().getName(); - if (Collections.binarySearch(mPreferenceClassNames, name) < 0) { - convertView = null; - } } - + return preference.getView(convertView, parent); } @@ -225,8 +259,9 @@ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeIn return IGNORE_ITEM_VIEW_TYPE; } - final String name = preference.getClass().getName(); - int viewType = Collections.binarySearch(mPreferenceClassNames, name); + mTempPreferenceLayout = createPreferenceLayout(preference, mTempPreferenceLayout); + + int viewType = Collections.binarySearch(mPreferenceLayouts, mTempPreferenceLayout); if (viewType < 0) { // This is a class that was seen after we returned the count, so // don't recycle it. @@ -242,7 +277,7 @@ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeIn mHasReturnedViewTypeCount = true; } - return Math.max(1, mPreferenceClassNames.size()); + return Math.max(1, mPreferenceLayouts.size()); } } |