Merge change Ia98129b9 into eclair-mr2
* changes: Fix preference caching to increase recycling of preference views.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user