am 446aeb1c: Merge change Ia98129b9 into eclair-mr2

Merge commit '446aeb1c3d2bb4df3ca73b0d88ef1a7ae0f93d53' into eclair-mr2-plus-aosp

* commit '446aeb1c3d2bb4df3ca73b0d88ef1a7ae0f93d53':
  Fix preference caching to increase recycling of preference views.
This commit is contained in:
Amith Yamasani
2009-10-07 12:09:08 -07:00
committed by Android Git Automerger
2 changed files with 72 additions and 38 deletions

View File

@@ -188,17 +188,7 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis
mContext = context; mContext = context;
TypedArray a = context.obtainStyledAttributes(attrs, TypedArray a = context.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.Preference); com.android.internal.R.styleable.Preference, defStyle, 0);
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);
for (int i = a.getIndexCount(); i >= 0; i--) { for (int i = a.getIndexCount(); i >= 0; i--) {
int attr = a.getIndex(i); int attr = a.getIndex(i);
switch (attr) { switch (attr) {
@@ -252,6 +242,11 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis
} }
} }
a.recycle(); 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) * @see #setWidgetLayoutResource(int)
*/ */
public void setLayoutResource(int layoutResId) { public void setLayoutResource(int layoutResId) {
if (layoutResId != mLayoutResId) {
if (!mHasSpecifiedLayout) { // Layout changed
mHasSpecifiedLayout = true; mHasSpecifiedLayout = true;
} }
mLayoutResId = layoutResId; mLayoutResId = layoutResId;
} }
@@ -360,6 +355,10 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis
* @see #setLayoutResource(int) * @see #setLayoutResource(int)
*/ */
public void setWidgetLayoutResource(int widgetLayoutResId) { public void setWidgetLayoutResource(int widgetLayoutResId) {
if (widgetLayoutResId != mWidgetLayoutResId) {
// Layout changed
mHasSpecifiedLayout = true;
}
mWidgetLayoutResId = widgetLayoutResId; mWidgetLayoutResId = widgetLayoutResId;
} }

View File

@@ -69,7 +69,9 @@ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeIn
* count once--when the adapter is being set). We will not recycle views for * count once--when the adapter is being set). We will not recycle views for
* Preference subclasses seen after the count has been returned. * 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. * 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) { public PreferenceGroupAdapter(PreferenceGroup preferenceGroup) {
mPreferenceGroup = preferenceGroup; mPreferenceGroup = preferenceGroup;
// If this group gets or loses any children, let us know // If this group gets or loses any children, let us know
mPreferenceGroup.setOnPreferenceChangeInternalListener(this); mPreferenceGroup.setOnPreferenceChangeInternalListener(this);
mPreferenceList = new ArrayList<Preference>(); mPreferenceList = new ArrayList<Preference>();
mPreferenceClassNames = new ArrayList<String>(); mPreferenceLayouts = new ArrayList<PreferenceLayout>();
syncMyPreferences(); syncMyPreferences();
} }
@@ -102,7 +127,7 @@ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeIn
if (mIsSyncing) { if (mIsSyncing) {
return; return;
} }
mIsSyncing = true; mIsSyncing = true;
} }
@@ -128,7 +153,7 @@ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeIn
preferences.add(preference); preferences.add(preference);
if (!mHasReturnedViewTypeCount) { if (!mHasReturnedViewTypeCount && !preference.hasSpecifiedLayout()) {
addPreferenceClassName(preference); 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) { private void addPreferenceClassName(Preference preference) {
final String name = preference.getClass().getName(); final PreferenceLayout pl = createPreferenceLayout(preference, null);
int insertPos = Collections.binarySearch(mPreferenceClassNames, name); int insertPos = Collections.binarySearch(mPreferenceLayouts, pl);
// Only insert if it doesn't exist (when it is negative). // Only insert if it doesn't exist (when it is negative).
if (insertPos < 0) { if (insertPos < 0) {
// Convert to insert index // Convert to insert index
insertPos = insertPos * -1 - 1; 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) { public View getView(int position, View convertView, ViewGroup parent) {
final Preference preference = this.getItem(position); final Preference preference = this.getItem(position);
// Build a PreferenceLayout to compare with known ones that are cacheable.
if (preference.hasSpecifiedLayout()) { mTempPreferenceLayout = createPreferenceLayout(preference, mTempPreferenceLayout);
// If the preference had specified a layout (as opposed to the
// default), don't use convert views. // 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; 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); return preference.getView(convertView, parent);
} }
@@ -225,8 +259,9 @@ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeIn
return IGNORE_ITEM_VIEW_TYPE; return IGNORE_ITEM_VIEW_TYPE;
} }
final String name = preference.getClass().getName(); mTempPreferenceLayout = createPreferenceLayout(preference, mTempPreferenceLayout);
int viewType = Collections.binarySearch(mPreferenceClassNames, name);
int viewType = Collections.binarySearch(mPreferenceLayouts, mTempPreferenceLayout);
if (viewType < 0) { if (viewType < 0) {
// This is a class that was seen after we returned the count, so // This is a class that was seen after we returned the count, so
// don't recycle it. // don't recycle it.
@@ -242,7 +277,7 @@ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeIn
mHasReturnedViewTypeCount = true; mHasReturnedViewTypeCount = true;
} }
return Math.max(1, mPreferenceClassNames.size()); return Math.max(1, mPreferenceLayouts.size());
} }
} }