From 2071eda150c4ade320fa91ec99678114afbd223e Mon Sep 17 00:00:00 2001 From: Jason Monk Date: Thu, 25 Feb 2016 13:55:48 -0500 Subject: [PATCH] Workarounds to avoid removing all prefs Removing all prefs causes ugly animations, so avoid it at all cost and cache all the prefs (while still added) as long as possible. Bug: 26271353 Change-Id: I33b84d751938b460f4b66c0158057407dd45d974 --- .../settings/SettingsPreferenceFragment.java | 24 +++++++++ .../bluetooth/BluetoothDevicePreference.java | 4 ++ .../settings/bluetooth/BluetoothSettings.java | 49 ++++++++++--------- .../DeviceListPreferenceFragment.java | 14 ++++-- .../android/settings/wifi/WifiSettings.java | 10 ++-- 5 files changed, 72 insertions(+), 29 deletions(-) diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java index 6144f72d7e7..daa2f1b7c11 100644 --- a/src/com/android/settings/SettingsPreferenceFragment.java +++ b/src/com/android/settings/SettingsPreferenceFragment.java @@ -34,6 +34,7 @@ import android.support.v7.preference.PreferenceViewHolder; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.text.TextUtils; +import android.util.ArrayMap; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; @@ -97,6 +98,7 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF private View mEmptyView; private LinearLayoutManager mLayoutManager; private HighlightablePreferenceGroupAdapter mAdapter; + private ArrayMap mPreferenceCache; @Override public void onCreate(Bundle icicle) { @@ -367,6 +369,28 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF return mAdapter; } + protected void cacheRemoveAllPrefs(PreferenceGroup group) { + mPreferenceCache = new ArrayMap(); + final int N = group.getPreferenceCount(); + for (int i = 0; i < N; i++) { + Preference p = group.getPreference(i); + if (TextUtils.isEmpty(p.getKey())) { + continue; + } + mPreferenceCache.put(p.getKey(), p); + } + } + + protected Preference getCachedPreference(String key) { + return mPreferenceCache != null ? mPreferenceCache.remove(key) : null; + } + + protected void removeCachedPrefs(PreferenceGroup group) { + for (Preference p : mPreferenceCache.values()) { + group.removePreference(p); + } + } + private void highlightPreference(String key) { final int position = canUseListViewForHighLighting(key); if (position >= 0) { diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java index 4544a50f9f7..6d953519768 100644 --- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java +++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java @@ -84,6 +84,10 @@ public final class BluetoothDevicePreference extends Preference implements onDeviceAttributesChanged(); } + void rebind() { + notifyChanged(); + } + CachedBluetoothDevice getCachedDevice() { return mCachedDevice; } diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java index 7db915faa86..ec0479e3426 100644 --- a/src/com/android/settings/bluetooth/BluetoothSettings.java +++ b/src/com/android/settings/bluetooth/BluetoothSettings.java @@ -39,7 +39,6 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.widget.TextView; - import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsProto.MetricsEvent; import com.android.settings.LinkifyUtils; @@ -77,6 +76,8 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem private static final String BTOPP_ACTION_OPEN_RECEIVED_FILES = "android.btopp.intent.action.OPEN_RECEIVED_FILES"; + private static final String KEY_PAIRED_DEVICES = "paired_devices"; + private static View mSettingsDialogView = null; private BluetoothEnabler mBluetoothEnabler; @@ -154,6 +155,21 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem void addPreferencesForActivity() { addPreferencesFromResource(R.xml.bluetooth_settings); + mPairedDevicesCategory = new PreferenceCategory(getPrefContext()); + mPairedDevicesCategory.setKey(KEY_PAIRED_DEVICES); + mPairedDevicesCategory.setOrder(1); + getPreferenceScreen().addPreference(mPairedDevicesCategory); + + mAvailableDevicesCategory = new BluetoothProgressCategory(getActivity()); + mAvailableDevicesCategory.setSelectable(false); + mAvailableDevicesCategory.setOrder(2); + getPreferenceScreen().addPreference(mAvailableDevicesCategory); + + mMyDevicePreference = new Preference(getPrefContext()); + mMyDevicePreference.setSelectable(false); + mMyDevicePreference.setOrder(3); + getPreferenceScreen().addPreference(mMyDevicePreference); + setHasOptionsMenu(true); } @@ -275,14 +291,15 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem private void addDeviceCategory(PreferenceGroup preferenceGroup, int titleId, BluetoothDeviceFilter.Filter filter, boolean addCachedDevices) { + cacheRemoveAllPrefs(preferenceGroup); preferenceGroup.setTitle(titleId); - getPreferenceScreen().addPreference(preferenceGroup); setFilter(filter); setDeviceListGroup(preferenceGroup); if (addCachedDevices) { addCachedDevices(); } preferenceGroup.setEnabled(true); + removeCachedPrefs(preferenceGroup); } private void updateContent(int bluetoothState) { @@ -291,8 +308,6 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem switch (bluetoothState) { case BluetoothAdapter.STATE_ON: - preferenceScreen.removeAll(); - preferenceScreen.setOrderingAsAdded(true); mDevicePreferenceMap.clear(); if (isUiRestricted()) { @@ -301,44 +316,32 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem } // Paired devices category - if (mPairedDevicesCategory == null) { - mPairedDevicesCategory = new PreferenceCategory(getPrefContext()); - } else { - mPairedDevicesCategory.removeAll(); - } addDeviceCategory(mPairedDevicesCategory, R.string.bluetooth_preference_paired_devices, BluetoothDeviceFilter.BONDED_DEVICE_FILTER, true); int numberOfPairedDevices = mPairedDevicesCategory.getPreferenceCount(); if (isUiRestricted() || numberOfPairedDevices <= 0) { - preferenceScreen.removePreference(mPairedDevicesCategory); + if (preferenceScreen.findPreference(KEY_PAIRED_DEVICES) != null) { + preferenceScreen.removePreference(mPairedDevicesCategory); + } + } else { + if (preferenceScreen.findPreference(KEY_PAIRED_DEVICES) == null) { + preferenceScreen.addPreference(mPairedDevicesCategory); + } } // Available devices category - if (mAvailableDevicesCategory == null) { - mAvailableDevicesCategory = new BluetoothProgressCategory(getActivity()); - mAvailableDevicesCategory.setSelectable(false); - } else { - mAvailableDevicesCategory.removeAll(); - } addDeviceCategory(mAvailableDevicesCategory, R.string.bluetooth_preference_found_devices, BluetoothDeviceFilter.UNBONDED_DEVICE_FILTER, mInitialScanStarted); - int numberOfAvailableDevices = mAvailableDevicesCategory.getPreferenceCount(); if (!mInitialScanStarted) { startScanning(); } - if (mMyDevicePreference == null) { - mMyDevicePreference = new Preference(getPrefContext()); - } - mMyDevicePreference.setSummary(getResources().getString( R.string.bluetooth_is_visible_message, mLocalAdapter.getName())); - mMyDevicePreference.setSelectable(false); - preferenceScreen.addPreference(mMyDevicePreference); getActivity().invalidateOptionsMenu(); diff --git a/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java b/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java index 607db598f61..1eea942076f 100644 --- a/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java +++ b/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java @@ -176,11 +176,19 @@ public abstract class DeviceListPreferenceFragment extends return; } - BluetoothDevicePreference preference = new BluetoothDevicePreference( - getPrefContext(), cachedDevice); + String key = cachedDevice.getDevice().getAddress(); + BluetoothDevicePreference preference = (BluetoothDevicePreference) getCachedPreference(key); + + if (preference == null) { + preference = new BluetoothDevicePreference(getPrefContext(), cachedDevice); + mDeviceListGroup.addPreference(preference); + } else { + // Tell the preference it is being re-used in case there is new info in the + // cached device. + preference.rebind(); + } initDevicePreference(preference); - mDeviceListGroup.addPreference(preference); mDevicePreferenceMap.put(cachedDevice, preference); } diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java index 12e5c542721..783121b48a2 100644 --- a/src/com/android/settings/wifi/WifiSettings.java +++ b/src/com/android/settings/wifi/WifiSettings.java @@ -649,19 +649,22 @@ public class WifiSettings extends RestrictedSettingsFragment boolean hasAvailableAccessPoints = false; int index = 0; + cacheRemoveAllPrefs(getPreferenceScreen()); for (AccessPoint accessPoint : accessPoints) { // Ignore access points that are out of range. if (accessPoint.getLevel() != -1) { + String key = accessPoint.getBssid(); hasAvailableAccessPoints = true; - if (accessPoint.getTag() != null) { - final Preference pref = (Preference) accessPoint.getTag(); + LongPressAccessPointPreference pref = (LongPressAccessPointPreference) + getCachedPreference(key); + if (pref != null) { pref.setOrder(index++); - getPreferenceScreen().addPreference(pref); continue; } LongPressAccessPointPreference preference = new LongPressAccessPointPreference(accessPoint, getPrefContext(), mUserBadgeCache, false, this); + preference.setKey(key); preference.setOrder(index++); if (mOpenSsid != null && mOpenSsid.equals(accessPoint.getSsidStr()) @@ -674,6 +677,7 @@ public class WifiSettings extends RestrictedSettingsFragment accessPoint.setListener(this); } } + removeCachedPrefs(getPreferenceScreen()); if (!hasAvailableAccessPoints) { setProgressBarVisible(true); Preference pref = new Preference(getContext()) {