Fix inconsist color filling on collapsing toolbar

Some pages are updating the background color for action bar after action
bar is created, which will break the animation of collapsing toolbar. It
also causes the different color filled in the status bar and collapsing
toolbar area separately. Removing the styleActionbar method from
EntityHeaderController can fix this issue.

Fix: 187019164
Test: robotests && visual verified
1) Settings -> Apps -> See all apps -> pick up either app -> Mobile data
& Wi-Fi
2) Scrolling the content and see if the toolbar has the different color
between status bar and toolbar

Change-Id: Ic0842b9e6c48662872694534a3696c4b8900481f
This commit is contained in:
Mill Chen
2021-05-06 00:24:37 +08:00
parent d7caf65594
commit efbcc69cc4
10 changed files with 2 additions and 121 deletions

View File

@@ -29,11 +29,10 @@ import com.android.settingslib.applications.AppUtils;
import com.android.settingslib.applications.ApplicationsState.AppEntry; import com.android.settingslib.applications.ApplicationsState.AppEntry;
import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.widget.LayoutPreference; import com.android.settingslib.widget.LayoutPreference;
public class AppHeaderViewPreferenceController extends BasePreferenceController public class AppHeaderViewPreferenceController extends BasePreferenceController
implements AppInfoDashboardFragment.Callback, LifecycleObserver, OnStart { implements AppInfoDashboardFragment.Callback, LifecycleObserver {
private static final String KEY_HEADER = "header_view"; private static final String KEY_HEADER = "header_view";
@@ -67,19 +66,13 @@ public class AppHeaderViewPreferenceController extends BasePreferenceController
final Activity activity = mParent.getActivity(); final Activity activity = mParent.getActivity();
mEntityHeaderController = EntityHeaderController mEntityHeaderController = EntityHeaderController
.newInstance(activity, mParent, mHeader.findViewById(R.id.entity_header)) .newInstance(activity, mParent, mHeader.findViewById(R.id.entity_header))
.setRecyclerView(mParent.getListView(), mLifecycle)
.setPackageName(mPackageName) .setPackageName(mPackageName)
.setButtonActions(EntityHeaderController.ActionType.ACTION_NONE, .setButtonActions(EntityHeaderController.ActionType.ACTION_NONE,
EntityHeaderController.ActionType.ACTION_NONE) EntityHeaderController.ActionType.ACTION_NONE)
.bindHeaderButtons(); .bindHeaderButtons();
} }
@Override
public void onStart() {
mEntityHeaderController
.setRecyclerView(mParent.getListView(), mLifecycle)
.styleActionBar(mParent.getActivity());
}
@Override @Override
public void refreshUi() { public void refreshUi() {
setAppLabelAndIcon(mParent.getPackageInfo(), mParent.getAppEntry()); setAppLabelAndIcon(mParent.getPackageInfo(), mParent.getAppEntry());

View File

@@ -25,7 +25,6 @@ import android.util.IconDrawableFactory;
import android.view.View; import android.view.View;
import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import com.android.settings.R; import com.android.settings.R;
@@ -36,7 +35,6 @@ import com.android.settings.notification.NotificationBackend;
import com.android.settings.widget.EntityHeaderController; import com.android.settings.widget.EntityHeaderController;
import com.android.settingslib.applications.AppUtils; import com.android.settingslib.applications.AppUtils;
import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.widget.LayoutPreference; import com.android.settingslib.widget.LayoutPreference;
public class HeaderPreferenceController extends BasePreferenceController public class HeaderPreferenceController extends BasePreferenceController
@@ -127,11 +125,4 @@ public class HeaderPreferenceController extends BasePreferenceController
.done(mFragment.getActivity(), mContext); .done(mFragment.getActivity(), mContext);
pref.findViewById(R.id.entity_header).setVisibility(View.VISIBLE); pref.findViewById(R.id.entity_header).setVisibility(View.VISIBLE);
} }
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onStart() {
if (mHeaderController != null) {
mHeaderController.styleActionBar(mFragment.getActivity());
}
}
} }

View File

@@ -178,7 +178,6 @@ public class DataUsageSummaryPreferenceController extends TelephonyBasePreferenc
} }
RecyclerView view = mFragment.getListView(); RecyclerView view = mFragment.getListView();
mEntityHeaderController.setRecyclerView(view, mLifecycle); mEntityHeaderController.setRecyclerView(view, mLifecycle);
mEntityHeaderController.styleActionBar((Activity) mContext);
} }
@VisibleForTesting @VisibleForTesting

View File

@@ -122,9 +122,6 @@ public class ConversationHeaderPreferenceController extends NotificationPreferen
@OnLifecycleEvent(Lifecycle.Event.ON_START) @OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onStart() { public void onStart() {
mStarted = true; mStarted = true;
if (mHeaderController != null) {
mHeaderController.styleActionBar(mFragment.getActivity());
}
} }
@VisibleForTesting @VisibleForTesting

View File

@@ -121,9 +121,6 @@ public class HeaderPreferenceController extends NotificationPreferenceController
@OnLifecycleEvent(Lifecycle.Event.ON_START) @OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onStart() { public void onStart() {
mStarted = true; mStarted = true;
if (mHeaderController != null) {
mHeaderController.styleActionBar(mFragment.getActivity());
}
} }
@VisibleForTesting @VisibleForTesting

View File

@@ -18,15 +18,12 @@ package com.android.settings.widget;
import android.annotation.IdRes; import android.annotation.IdRes;
import android.annotation.UserIdInt; import android.annotation.UserIdInt;
import android.app.ActionBar;
import android.app.Activity; import android.app.Activity;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.UserHandle; import android.os.UserHandle;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
@@ -48,7 +45,6 @@ import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.applications.ApplicationsState; import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.widget.ActionBarShadowController;
import com.android.settingslib.widget.LayoutPreference; import com.android.settingslib.widget.LayoutPreference;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
@@ -244,7 +240,6 @@ public class EntityHeaderController {
* Done mutating entity header, rebinds everything (optionally skip rebinding buttons). * Done mutating entity header, rebinds everything (optionally skip rebinding buttons).
*/ */
public View done(Activity activity, boolean rebindActions) { public View done(Activity activity, boolean rebindActions) {
styleActionBar(activity);
ImageView iconView = mHeader.findViewById(R.id.entity_header_icon); ImageView iconView = mHeader.findViewById(R.id.entity_header_icon);
if (iconView != null) { if (iconView != null) {
iconView.setImageDrawable(mIcon); iconView.setImageDrawable(mIcon);
@@ -302,32 +297,6 @@ public class EntityHeaderController {
return; return;
} }
/**
* Styles the action bar (elevation, scrolling behaviors, color, etc).
* <p/>
* This method must be called after {@link Fragment#onCreate(Bundle)}.
*/
public EntityHeaderController styleActionBar(Activity activity) {
if (activity == null) {
Log.w(TAG, "No activity, cannot style actionbar.");
return this;
}
final ActionBar actionBar = activity.getActionBar();
if (actionBar == null) {
Log.w(TAG, "No actionbar, cannot style actionbar.");
return this;
}
actionBar.setBackgroundDrawable(
new ColorDrawable(
Utils.getColorAttrDefaultColor(activity, android.R.attr.colorPrimaryDark)));
actionBar.setElevation(0);
if (mRecyclerView != null && mLifecycle != null) {
ActionBarShadowController.attachToView(mActivity, mLifecycle, mRecyclerView);
}
return this;
}
/** /**
* Done mutating entity header, rebinds everything. * Done mutating entity header, rebinds everything.
*/ */

View File

@@ -16,23 +16,16 @@
package com.android.settings.applications.appinfo; package com.android.settings.applications.appinfo;
import static androidx.lifecycle.Lifecycle.Event.ON_START;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.app.ActionBar;
import android.content.Context; import android.content.Context;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;
@@ -116,18 +109,4 @@ public class AppHeaderViewPreferenceControllerTest {
assertThat(title).isNotNull(); assertThat(title).isNotNull();
assertThat(title.getText()).isEqualTo(appLabel); assertThat(title.getText()).isEqualTo(appLabel);
} }
@Test
public void onStart_shouldStyleActionBar() {
final ActionBar actionBar = mock(ActionBar.class);
when(mActivity.getActionBar()).thenReturn(actionBar);
mController.displayPreference(mScreen);
verifyZeroInteractions(actionBar);
mLifecycle.handleLifecycleEvent(ON_START);
verify(actionBar).setBackgroundDrawable(any(Drawable.class));
}
} }

View File

@@ -29,7 +29,6 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
@@ -386,7 +385,6 @@ public class DataUsageSummaryPreferenceControllerTest {
verify(mHeaderController) verify(mHeaderController)
.setRecyclerView(any(RecyclerView.class), any(Lifecycle.class)); .setRecyclerView(any(RecyclerView.class), any(Lifecycle.class));
verify(mHeaderController).styleActionBar(any(Activity.class));
} }
private DataUsageController.DataUsageInfo createTestDataUsageInfo(long now) { private DataUsageController.DataUsageInfo createTestDataUsageInfo(long now) {

View File

@@ -17,13 +17,9 @@
package com.android.settings.fuelgauge; package com.android.settings.fuelgauge;
import static androidx.lifecycle.Lifecycle.Event.ON_START;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
@@ -41,7 +37,6 @@ import android.text.TextUtils;
import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleOwner;
import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.core.BasePreferenceController; import com.android.settings.core.BasePreferenceController;
@@ -283,17 +278,6 @@ public class BatteryHeaderPreferenceControllerTest {
verify(mBatteryUsageProgressBarPref).setBottomSummary(null); verify(mBatteryUsageProgressBarPref).setBottomSummary(null);
} }
@Test
public void onStart_shouldStyleActionBar() {
when(mEntityHeaderController.setRecyclerView(nullable(RecyclerView.class), eq(mLifecycle)))
.thenReturn(mEntityHeaderController);
mController.displayPreference(mPreferenceScreen);
mLifecycle.handleLifecycleEvent(ON_START);
verify(mEntityHeaderController).styleActionBar(mActivity);
}
@Test @Test
public void quickUpdateHeaderPreference_onlyUpdateBatteryLevelAndChargingState() { public void quickUpdateHeaderPreference_onlyUpdateBatteryLevelAndChargingState() {
mController.quickUpdateHeaderPreference(); mController.quickUpdateHeaderPreference();

View File

@@ -26,13 +26,11 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.app.ActionBar;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.graphics.drawable.ColorDrawable;
import android.os.UserHandle; import android.os.UserHandle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@@ -302,30 +300,6 @@ public class EntityHeaderControllerTest {
.isEqualTo(View.GONE); .isEqualTo(View.GONE);
} }
@Test
public void styleActionBar_invalidObjects_shouldNotCrash() {
mController = EntityHeaderController.newInstance(mActivity, mFragment, null);
mController.styleActionBar(null);
when(mActivity.getActionBar()).thenReturn(null);
mController.styleActionBar(mActivity);
verify(mActivity).getActionBar();
}
@Test
public void styleActionBar_setElevationAndBackground() {
final ActionBar actionBar = mActivity.getActionBar();
mController = EntityHeaderController.newInstance(mActivity, mFragment, null);
mController.styleActionBar(mActivity);
verify(actionBar).setElevation(0);
// Enforce a color drawable as background here, as image based drawables might not be
// wide enough to cover entire action bar.
verify(actionBar).setBackgroundDrawable(any(ColorDrawable.class));
}
@Test @Test
public void initAppHeaderController_appHeaderNull_useFragmentContext() { public void initAppHeaderController_appHeaderNull_useFragmentContext() {
mController = EntityHeaderController.newInstance(mActivity, mFragment, null); mController = EntityHeaderController.newInstance(mActivity, mFragment, null);