Fix flicker for AppDataUsage when zero usage
When the page is entered from the AppInfoDashboardFragment, there is no way to know whether the cycle data is available before finished the async loading. If it's zero usage, the cycle spinner will be removed, which cause a flicker. Temporarily disable the preference list's animator before initial page updates can solve this issue. This also fix another flicker on this page when the background data is off. Fix: 233963355 Test: manual visual test Change-Id: I795ed95e15bb3216fa17adfd4f57faf5fd92fa00
This commit is contained in:
@@ -40,6 +40,8 @@ import androidx.loader.content.Loader;
|
|||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
import androidx.preference.Preference.OnPreferenceChangeListener;
|
import androidx.preference.Preference.OnPreferenceChangeListener;
|
||||||
import androidx.preference.PreferenceCategory;
|
import androidx.preference.PreferenceCategory;
|
||||||
|
import androidx.recyclerview.widget.DefaultItemAnimator;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.applications.AppInfoBase;
|
import com.android.settings.applications.AppInfoBase;
|
||||||
@@ -105,6 +107,7 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC
|
|||||||
private Context mContext;
|
private Context mContext;
|
||||||
private ArrayList<Long> mCycles;
|
private ArrayList<Long> mCycles;
|
||||||
private long mSelectedCycle;
|
private long mSelectedCycle;
|
||||||
|
private boolean mIsLoading;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle icicle) {
|
||||||
@@ -226,6 +229,16 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC
|
|||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
// No animations will occur before:
|
||||||
|
// - LOADER_APP_USAGE_DATA initially updates the cycle
|
||||||
|
// - updatePrefs() initially updates the preference visibility
|
||||||
|
// This is mainly for the cycle spinner, because when the page is entered from the
|
||||||
|
// AppInfoDashboardFragment, there is no way to know whether the cycle data is available
|
||||||
|
// before finished the async loading.
|
||||||
|
// The animator will be set back if any page updates happens after loading, in
|
||||||
|
// setBackPreferenceListAnimatorIfLoaded().
|
||||||
|
mIsLoading = true;
|
||||||
|
getListView().setItemAnimator(null);
|
||||||
if (mDataSaverBackend != null) {
|
if (mDataSaverBackend != null) {
|
||||||
mDataSaverBackend.addListener(this);
|
mDataSaverBackend.addListener(this);
|
||||||
}
|
}
|
||||||
@@ -297,7 +310,25 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets back the preference list's animator if the loading is finished.
|
||||||
|
*
|
||||||
|
* The preference list's animator was temporarily removed before loading in onResume().
|
||||||
|
* When need to update the preference visibility in this page after the loading, adding the
|
||||||
|
* animator back to keeping the usual animations.
|
||||||
|
*/
|
||||||
|
private void setBackPreferenceListAnimatorIfLoaded() {
|
||||||
|
if (mIsLoading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RecyclerView recyclerView = getListView();
|
||||||
|
if (recyclerView.getItemAnimator() == null) {
|
||||||
|
recyclerView.setItemAnimator(new DefaultItemAnimator());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updatePrefs(boolean restrictBackground, boolean unrestrictData) {
|
private void updatePrefs(boolean restrictBackground, boolean unrestrictData) {
|
||||||
|
setBackPreferenceListAnimatorIfLoaded();
|
||||||
final EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfMeteredDataRestricted(
|
final EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfMeteredDataRestricted(
|
||||||
mContext, mPackageName, UserHandle.getUserId(mAppItem.key));
|
mContext, mPackageName, UserHandle.getUserId(mAppItem.key));
|
||||||
if (mRestrictBackground != null) {
|
if (mRestrictBackground != null) {
|
||||||
@@ -448,6 +479,7 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC
|
|||||||
} else {
|
} else {
|
||||||
bindData(0 /* position */);
|
bindData(0 /* position */);
|
||||||
}
|
}
|
||||||
|
mIsLoading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -48,6 +48,7 @@ import androidx.fragment.app.FragmentActivity;
|
|||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
import androidx.preference.PreferenceScreen;
|
import androidx.preference.PreferenceScreen;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.android.settings.applications.AppInfoBase;
|
import com.android.settings.applications.AppInfoBase;
|
||||||
import com.android.settings.testutils.FakeFeatureFactory;
|
import com.android.settings.testutils.FakeFeatureFactory;
|
||||||
@@ -240,6 +241,7 @@ public class AppDataUsageTest {
|
|||||||
ReflectionHelpers.setField(mFragment, "mUnrestrictedData", unrestrictedDataPref);
|
ReflectionHelpers.setField(mFragment, "mUnrestrictedData", unrestrictedDataPref);
|
||||||
ReflectionHelpers.setField(mFragment, "mDataSaverBackend", dataSaverBackend);
|
ReflectionHelpers.setField(mFragment, "mDataSaverBackend", dataSaverBackend);
|
||||||
ReflectionHelpers.setField(mFragment.services, "mPolicyManager", networkPolicyManager);
|
ReflectionHelpers.setField(mFragment.services, "mPolicyManager", networkPolicyManager);
|
||||||
|
when(mFragment.getListView()).thenReturn(mock(RecyclerView.class));
|
||||||
|
|
||||||
ShadowRestrictedLockUtilsInternal.setRestricted(true);
|
ShadowRestrictedLockUtilsInternal.setRestricted(true);
|
||||||
doReturn(NetworkPolicyManager.POLICY_NONE).when(networkPolicyManager)
|
doReturn(NetworkPolicyManager.POLICY_NONE).when(networkPolicyManager)
|
||||||
|
Reference in New Issue
Block a user