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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user