[DO NOT MERGE] Fix flicker for Data Usage page am: 5a2f5ecff5
am: 298ca56920
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/18281653 Change-Id: I140a085bc4a18196f28295c1835eebd02f77665e Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -17,7 +17,8 @@
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="usage_amount">
|
||||
android:key="usage_amount"
|
||||
android:title="@string/summary_placeholder">
|
||||
|
||||
<com.android.settings.datausage.ChartDataUsagePreference
|
||||
android:key="chart_data" />
|
||||
|
@@ -21,7 +21,6 @@ import com.android.settingslib.net.NetworkCycleData;
|
||||
import com.android.settingslib.widget.SettingsSpinnerAdapter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class CycleAdapter extends SettingsSpinnerAdapter<CycleAdapter.CycleItem> {
|
||||
|
||||
@@ -67,7 +66,7 @@ public class CycleAdapter extends SettingsSpinnerAdapter<CycleAdapter.CycleItem>
|
||||
* Rebuild list based on network data. Always selects the newest item,
|
||||
* updating the inspection range on chartData.
|
||||
*/
|
||||
public boolean updateCycleList(List<? extends NetworkCycleData> cycleData) {
|
||||
public void updateCycleList(List<? extends NetworkCycleData> cycleData) {
|
||||
mSpinner.setOnItemSelectedListener(mListener);
|
||||
// stash away currently selected cycle to try restoring below
|
||||
final CycleAdapter.CycleItem previousItem = (CycleAdapter.CycleItem)
|
||||
@@ -83,16 +82,7 @@ public class CycleAdapter extends SettingsSpinnerAdapter<CycleAdapter.CycleItem>
|
||||
if (getCount() > 0) {
|
||||
final int position = findNearestPosition(previousItem);
|
||||
mSpinner.setSelection(position);
|
||||
|
||||
// only force-update cycle when changed; skipping preserves any
|
||||
// user-defined inspection region.
|
||||
final CycleAdapter.CycleItem selectedItem = getItem(position);
|
||||
if (!Objects.equals(selectedItem, previousItem)) {
|
||||
mListener.onItemSelected(null, null, position, 0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -69,6 +69,7 @@ import com.android.settingslib.net.UidDetailProvider;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Panel showing data usage history across various networks, including options
|
||||
@@ -111,7 +112,11 @@ public class DataUsageList extends DataUsageBaseFragment
|
||||
|
||||
private ChartDataUsagePreference mChart;
|
||||
private List<NetworkCycleChartData> mCycleData;
|
||||
// Caches the cycles for startAppDataUsage usage, which need be cleared when resumed.
|
||||
private ArrayList<Long> mCycles;
|
||||
// Spinner will keep the selected cycle even after paused, this only keeps the displayed cycle,
|
||||
// which need be cleared when resumed.
|
||||
private CycleAdapter.CycleItem mLastDisplayedCycle;
|
||||
private UidDetailProvider mUidDetailProvider;
|
||||
private CycleAdapter mCycleAdapter;
|
||||
private Preference mUsageAmount;
|
||||
@@ -199,13 +204,15 @@ public class DataUsageList extends DataUsageBaseFragment
|
||||
|
||||
mLoadingViewController = new LoadingViewController(
|
||||
getView().findViewById(R.id.loading_container), getListView());
|
||||
mLoadingViewController.showLoadingViewDelayed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mLoadingViewController.showLoadingViewDelayed();
|
||||
mDataStateListener.start(mSubId);
|
||||
mCycles = null;
|
||||
mLastDisplayedCycle = null;
|
||||
|
||||
// kick off loader for network history
|
||||
// TODO: consider chaining two loaders together instead of reloading
|
||||
@@ -319,9 +326,46 @@ public class DataUsageList extends DataUsageBaseFragment
|
||||
}
|
||||
|
||||
// generate cycle list based on policy and available history
|
||||
if (mCycleAdapter.updateCycleList(mCycleData)) {
|
||||
updateDetailData();
|
||||
mCycleAdapter.updateCycleList(mCycleData);
|
||||
updateSelectedCycle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the chart and detail data when initial loaded or selected cycle changed.
|
||||
*/
|
||||
private void updateSelectedCycle() {
|
||||
// Avoid from updating UI after #onStop.
|
||||
if (!getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Avoid from updating UI when async query still on-going.
|
||||
// This could happen when a request from #onMobileDataEnabledChange.
|
||||
if (mCycleData == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int position = mCycleSpinner.getSelectedItemPosition();
|
||||
if (mCycleAdapter.getCount() == 0 || position < 0) {
|
||||
return;
|
||||
}
|
||||
final CycleAdapter.CycleItem cycle = mCycleAdapter.getItem(position);
|
||||
if (Objects.equals(cycle, mLastDisplayedCycle)) {
|
||||
// Avoid duplicate update to avoid page flash.
|
||||
return;
|
||||
}
|
||||
mLastDisplayedCycle = cycle;
|
||||
|
||||
if (LOGD) {
|
||||
Log.d(TAG, "showing cycle " + cycle + ", [start=" + cycle.start + ", end="
|
||||
+ cycle.end + "]");
|
||||
}
|
||||
|
||||
// update chart to show selected cycle, and update detail data
|
||||
// to match updated sweep bounds.
|
||||
mChart.setNetworkCycleData(mCycleData.get(position));
|
||||
|
||||
updateDetailData();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -495,33 +539,10 @@ public class DataUsageList extends DataUsageBaseFragment
|
||||
return Math.max(largest, item.total);
|
||||
}
|
||||
|
||||
private OnItemSelectedListener mCycleListener = new OnItemSelectedListener() {
|
||||
private final OnItemSelectedListener mCycleListener = new OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
final CycleAdapter.CycleItem cycle = (CycleAdapter.CycleItem)
|
||||
mCycleSpinner.getSelectedItem();
|
||||
|
||||
if (LOGD) {
|
||||
Log.d(TAG, "showing cycle " + cycle + ", start=" + cycle.start + ", end="
|
||||
+ cycle.end + "]");
|
||||
}
|
||||
|
||||
// Avoid from updating UI after #onStop.
|
||||
if (!getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Avoid from updating UI when async query still on-going.
|
||||
// This could happen when a request from #onMobileDataEnabledChange.
|
||||
if (mCycleData == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// update chart to show selected cycle, and update detail data
|
||||
// to match updated sweep bounds.
|
||||
mChart.setNetworkCycleData(mCycleData.get(position));
|
||||
|
||||
updateDetailData();
|
||||
updateSelectedCycle();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -14,6 +14,7 @@
|
||||
|
||||
package com.android.settings.datausage;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
@@ -28,6 +29,7 @@ import com.android.settings.R;
|
||||
public class SpinnerPreference extends Preference implements CycleAdapter.SpinnerInterface {
|
||||
|
||||
private CycleAdapter mAdapter;
|
||||
@Nullable
|
||||
private AdapterView.OnItemSelectedListener mListener;
|
||||
private Object mCurrentObject;
|
||||
private int mPosition;
|
||||
@@ -88,19 +90,24 @@ public class SpinnerPreference extends Preference implements CycleAdapter.Spinne
|
||||
view.findViewById(R.id.cycles_spinner).performClick();
|
||||
}
|
||||
|
||||
private final AdapterView.OnItemSelectedListener mOnSelectedListener
|
||||
= new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (mPosition == position) return;
|
||||
mPosition = position;
|
||||
mCurrentObject = mAdapter.getItem(position);
|
||||
mListener.onItemSelected(parent, view, position, id);
|
||||
}
|
||||
private final AdapterView.OnItemSelectedListener mOnSelectedListener =
|
||||
new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(
|
||||
AdapterView<?> parent, View view, int position, long id) {
|
||||
if (mPosition == position) return;
|
||||
mPosition = position;
|
||||
mCurrentObject = mAdapter.getItem(position);
|
||||
if (mListener != null) {
|
||||
mListener.onItemSelected(parent, view, position, id);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
mListener.onNothingSelected(parent);
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
if (mListener != null) {
|
||||
mListener.onNothingSelected(parent);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@@ -94,6 +94,7 @@ public class DataUsageListTest {
|
||||
mMobileDataEnabledListener);
|
||||
ReflectionHelpers.setField(mDataUsageList, "services", mNetworkServices);
|
||||
doReturn(mLoaderManager).when(mDataUsageList).getLoaderManager();
|
||||
mDataUsageList.mLoadingViewController = mock(LoadingViewController.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -207,8 +208,6 @@ public class DataUsageListTest {
|
||||
|
||||
@Test
|
||||
public void onLoadFinished_networkCycleDataCallback_shouldShowCycleSpinner() {
|
||||
final LoadingViewController loadingViewController = mock(LoadingViewController.class);
|
||||
mDataUsageList.mLoadingViewController = loadingViewController;
|
||||
final Spinner spinner = getSpinner(getHeader());
|
||||
spinner.setVisibility(View.INVISIBLE);
|
||||
mDataUsageList.mCycleSpinner = spinner;
|
||||
|
Reference in New Issue
Block a user