Skip to content

Commit 569ddac

Browse files
dsn5ftleticiarossi
authored andcommittedSep 12, 2023
[AppBarLayout] Fix dynamic status bar foreground lift on scroll color when using Tonal Surface Color
Resolves #3530 PiperOrigin-RevId: 564364138
1 parent 4e1b130 commit 569ddac

File tree

4 files changed

+47
-12
lines changed

4 files changed

+47
-12
lines changed
 

‎catalog/java/io/material/catalog/topappbar/TopAppBarCompressEffectFragment.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
import androidx.annotation.NonNull;
3232
import androidx.annotation.Nullable;
3333
import com.google.android.material.appbar.AppBarLayout;
34-
import com.google.android.material.shape.MaterialShapeDrawable;
34+
import com.google.android.material.color.MaterialColors;
3535
import com.google.android.material.tabs.TabLayout;
3636
import io.material.catalog.feature.DemoFragment;
3737
import io.material.catalog.feature.DemoUtils;
@@ -59,8 +59,8 @@ public View onCreateDemoView(
5959
activity.setSupportActionBar(toolbar);
6060

6161
AppBarLayout appBarLayout = view.findViewById(R.id.appbarlayout);
62-
appBarLayout.setStatusBarForeground(
63-
MaterialShapeDrawable.createWithElevationOverlay(requireContext()));
62+
appBarLayout.setStatusBarForegroundColor(
63+
MaterialColors.getColor(appBarLayout, R.attr.colorSurface));
6464

6565
TabLayout tabs = view.findViewById(R.id.tabs);
6666
ToggleButton showHideTabsButton = view.findViewById(R.id.show_hide_tabs_button);

‎catalog/java/io/material/catalog/topappbar/TopAppBarScrollingDemoFragment.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
import android.view.ViewGroup;
3030
import androidx.annotation.Nullable;
3131
import com.google.android.material.appbar.AppBarLayout;
32-
import com.google.android.material.shape.MaterialShapeDrawable;
32+
import com.google.android.material.color.MaterialColors;
3333
import io.material.catalog.feature.DemoFragment;
3434
import io.material.catalog.feature.DemoUtils;
3535

@@ -52,8 +52,8 @@ public View onCreateDemoView(
5252
activity.setSupportActionBar(toolbar);
5353

5454
AppBarLayout appBarLayout = view.findViewById(R.id.appbarlayout);
55-
appBarLayout.setStatusBarForeground(
56-
MaterialShapeDrawable.createWithElevationOverlay(requireContext()));
55+
appBarLayout.setStatusBarForegroundColor(
56+
MaterialColors.getColor(appBarLayout, R.attr.colorSurface));
5757

5858
return view;
5959
}

‎docs/components/TopAppBar.md

+9
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,15 @@ appBarLayout.setStatusBarForeground(
327327
MaterialShapeDrawable.createWithElevationOverlay(getContext()));
328328
```
329329

330+
Or if using Tonal Surface Colors instead of Elevation Overlays, you can simply
331+
set the `statusBarForeground` to `colorSurface` to let `AppBarLayout`
332+
automatically match the status bar color to its own background:
333+
334+
```
335+
appBarLayout.setStatusBarForegroundColor(
336+
MaterialColors.getColor(appBarLayout, R.attr.colorSurface));
337+
```
338+
330339
### Center aligned top app bar example
331340

332341
All of the same guidance and code from the sections above is relevant for Center

‎lib/java/com/google/android/material/appbar/AppBarLayout.java

+32-6
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
import com.google.android.material.animation.AnimationUtils;
7676
import com.google.android.material.animation.ArgbEvaluatorCompat;
7777
import com.google.android.material.appbar.AppBarLayout.BaseBehavior.SavedState;
78+
import com.google.android.material.color.MaterialColors;
7879
import com.google.android.material.drawable.DrawableUtils;
7980
import com.google.android.material.internal.ThemeEnforcement;
8081
import com.google.android.material.motion.MotionUtils;
@@ -220,6 +221,7 @@ public interface LiftOnScrollListener {
220221
private int[] tmpStatesArray;
221222

222223
@Nullable private Drawable statusBarForeground;
224+
@Nullable private Integer statusBarForegroundOriginalColor;
223225

224226
private final float appBarElevation;
225227

@@ -332,19 +334,29 @@ private void initializeLiftOnScrollWithColor(MaterialShapeDrawable background) {
332334
liftBackground.setAlpha(lifted ? 255 : 0);
333335
background.setAlpha(lifted ? 0 : 255);
334336

337+
ColorStateList colorSurface =
338+
MaterialColors.getColorStateListOrNull(getContext(), R.attr.colorSurface);
339+
335340
liftOnScrollColorUpdateListener =
336341
valueAnimator -> {
337342
float liftAlpha = (float) valueAnimator.getAnimatedValue();
338343
background.setAlpha((int) (255f - liftAlpha));
339344
liftBackground.setAlpha((int) liftAlpha);
340345

346+
int mixedColor =
347+
ArgbEvaluatorCompat.getInstance()
348+
.evaluate(
349+
liftAlpha / 255f,
350+
background.getResolvedTintColor(),
351+
liftBackground.getResolvedTintColor());
352+
if (statusBarForeground != null
353+
&& statusBarForegroundOriginalColor != null
354+
&& colorSurface != null
355+
&& statusBarForegroundOriginalColor == colorSurface.getDefaultColor()) {
356+
DrawableCompat.setTint(statusBarForeground, mixedColor);
357+
}
358+
341359
if (!liftOnScrollListeners.isEmpty()) {
342-
int mixedColor =
343-
ArgbEvaluatorCompat.getInstance()
344-
.evaluate(
345-
liftAlpha / 255f,
346-
background.getResolvedTintColor(),
347-
liftBackground.getResolvedTintColor());
348360
for (LiftOnScrollListener liftOnScrollListener : liftOnScrollListeners) {
349361
if (background.getFillColor() != null) {
350362
liftOnScrollListener.onUpdate(0, mixedColor);
@@ -447,6 +459,7 @@ public void setStatusBarForeground(@Nullable Drawable drawable) {
447459
statusBarForeground.setCallback(null);
448460
}
449461
statusBarForeground = drawable != null ? drawable.mutate() : null;
462+
statusBarForegroundOriginalColor = extractStatusBarForegroundColor();
450463
if (statusBarForeground != null) {
451464
if (statusBarForeground.isStateful()) {
452465
statusBarForeground.setState(getDrawableState());
@@ -497,6 +510,19 @@ public Drawable getStatusBarForeground() {
497510
return statusBarForeground;
498511
}
499512

513+
@Nullable
514+
private Integer extractStatusBarForegroundColor() {
515+
if (statusBarForeground instanceof MaterialShapeDrawable) {
516+
return ((MaterialShapeDrawable) statusBarForeground).getResolvedTintColor();
517+
}
518+
ColorStateList statusBarForegroundColorStateList =
519+
DrawableUtils.getColorStateListOrNull(statusBarForeground);
520+
if (statusBarForegroundColorStateList != null) {
521+
return statusBarForegroundColorStateList.getDefaultColor();
522+
}
523+
return null;
524+
}
525+
500526
@Override
501527
public void draw(@NonNull Canvas canvas) {
502528
super.draw(canvas);

0 commit comments

Comments
 (0)
Please sign in to comment.