Skip to content

Commit 1e9f5f0

Browse files
pekingmedsn5ft
authored andcommitted
[AppBarLayout] Simplified logics to animate the container color between lifted state and the default state.
PiperOrigin-RevId: 566754407
1 parent 8d83a31 commit 1e9f5f0

File tree

2 files changed

+28
-61
lines changed

2 files changed

+28
-61
lines changed

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

Lines changed: 23 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
import android.graphics.Rect;
3636
import android.graphics.drawable.ColorDrawable;
3737
import android.graphics.drawable.Drawable;
38-
import android.graphics.drawable.LayerDrawable;
3938
import android.os.Build;
4039
import android.os.Build.VERSION;
4140
import android.os.Build.VERSION_CODES;
@@ -73,7 +72,6 @@
7372
import androidx.core.view.accessibility.AccessibilityViewCommand;
7473
import androidx.customview.view.AbsSavedState;
7574
import com.google.android.material.animation.AnimationUtils;
76-
import com.google.android.material.animation.ArgbEvaluatorCompat;
7775
import com.google.android.material.appbar.AppBarLayout.BaseBehavior.SavedState;
7876
import com.google.android.material.color.MaterialColors;
7977
import com.google.android.material.drawable.DrawableUtils;
@@ -210,7 +208,7 @@ public interface LiftOnScrollListener {
210208
private boolean liftOnScroll;
211209
@IdRes private int liftOnScrollTargetViewId;
212210
@Nullable private WeakReference<View> liftOnScrollTargetView;
213-
@Nullable private final ColorStateList liftOnScrollColor;
211+
private final boolean hasLiftOnScrollColor;
214212
@Nullable private ValueAnimator liftOnScrollColorAnimator;
215213
@Nullable private AnimatorUpdateListener liftOnScrollColorUpdateListener;
216214
private final List<LiftOnScrollListener> liftOnScrollListeners = new ArrayList<>();
@@ -259,19 +257,19 @@ public AppBarLayout(@NonNull Context context, @Nullable AttributeSet attrs, int
259257

260258
ViewCompat.setBackground(this, a.getDrawable(R.styleable.AppBarLayout_android_background));
261259

262-
liftOnScrollColor =
263-
MaterialResources.getColorStateList(
264-
context, a, R.styleable.AppBarLayout_liftOnScrollColor);
260+
ColorStateList liftOnScrollColor =
261+
MaterialResources.getColorStateList(context, a, R.styleable.AppBarLayout_liftOnScrollColor);
262+
hasLiftOnScrollColor = liftOnScrollColor != null;
265263

266-
ColorStateList backgroundColorStateList =
267-
DrawableUtils.getColorStateListOrNull(getBackground());
268-
if (backgroundColorStateList != null) {
264+
ColorStateList originalBackgroundColor = DrawableUtils.getColorStateListOrNull(getBackground());
265+
if (originalBackgroundColor != null) {
269266
MaterialShapeDrawable materialShapeDrawable = new MaterialShapeDrawable();
270-
materialShapeDrawable.setFillColor(backgroundColorStateList);
267+
materialShapeDrawable.setFillColor(originalBackgroundColor);
271268
// If there is a lift on scroll color specified, we do not initialize the elevation overlay
272269
// and set the alpha to zero manually.
273270
if (liftOnScrollColor != null) {
274-
initializeLiftOnScrollWithColor(materialShapeDrawable);
271+
initializeLiftOnScrollWithColor(
272+
materialShapeDrawable, originalBackgroundColor, liftOnScrollColor);
275273
} else {
276274
initializeLiftOnScrollWithElevation(context, materialShapeDrawable);
277275
}
@@ -328,26 +326,20 @@ public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets)
328326
});
329327
}
330328

331-
private void initializeLiftOnScrollWithColor(MaterialShapeDrawable background) {
332-
MaterialShapeDrawable liftBackground = new MaterialShapeDrawable();
333-
liftBackground.setFillColor(liftOnScrollColor);
334-
liftBackground.setAlpha(lifted ? 255 : 0);
335-
background.setAlpha(lifted ? 0 : 255);
336-
329+
private void initializeLiftOnScrollWithColor(
330+
MaterialShapeDrawable background,
331+
@NonNull ColorStateList originalBackgroundColor,
332+
@NonNull ColorStateList liftOnScrollColor) {
337333
Integer colorSurface = MaterialColors.getColorOrNull(getContext(), R.attr.colorSurface);
338-
339334
liftOnScrollColorUpdateListener =
340335
valueAnimator -> {
341-
float liftAlpha = (float) valueAnimator.getAnimatedValue();
342-
background.setAlpha((int) (255f - liftAlpha));
343-
liftBackground.setAlpha((int) liftAlpha);
344-
336+
float liftProgress = (float) valueAnimator.getAnimatedValue();
345337
int mixedColor =
346-
ArgbEvaluatorCompat.getInstance()
347-
.evaluate(
348-
liftAlpha / 255f,
349-
background.getResolvedTintColor(),
350-
liftBackground.getResolvedTintColor());
338+
MaterialColors.layer(
339+
originalBackgroundColor.getDefaultColor(),
340+
liftOnScrollColor.getDefaultColor(),
341+
liftProgress);
342+
background.setFillColor(ColorStateList.valueOf(mixedColor));
351343
if (statusBarForeground != null
352344
&& statusBarForegroundOriginalColor != null
353345
&& statusBarForegroundOriginalColor.equals(colorSurface)) {
@@ -362,9 +354,7 @@ private void initializeLiftOnScrollWithColor(MaterialShapeDrawable background) {
362354
}
363355
}
364356
};
365-
366-
LayerDrawable layerBackground = new LayerDrawable(new Drawable[] {background, liftBackground});
367-
ViewCompat.setBackground(this, layerBackground);
357+
ViewCompat.setBackground(this, background);
368358
}
369359

370360
private void initializeLiftOnScrollWithElevation(
@@ -693,9 +683,6 @@ public CoordinatorLayout.Behavior<AppBarLayout> getBehavior() {
693683
@Nullable
694684
public MaterialShapeDrawable getMaterialShapeBackground() {
695685
Drawable background = getBackground();
696-
if (background instanceof LayerDrawable) {
697-
background = ((LayerDrawable) background).getDrawable(0);
698-
}
699686
return background instanceof MaterialShapeDrawable ? (MaterialShapeDrawable) background : null;
700687
}
701688

@@ -1043,10 +1030,10 @@ boolean setLiftedState(boolean lifted, boolean force) {
10431030
this.lifted = lifted;
10441031
refreshDrawableState();
10451032
if (isLiftOnScrollCompatibleBackground()) {
1046-
if (liftOnScrollColor != null) {
1033+
if (hasLiftOnScrollColor) {
10471034
// Only start the liftOnScrollColor based animation because the elevation based
10481035
// animation will happen via the lifted drawable state change and state list animator.
1049-
startLiftOnScrollColorAnimation(lifted ? 0 : 255, lifted ? 255 : 0);
1036+
startLiftOnScrollColorAnimation(lifted ? 0 : 1, lifted ? 1 : 0);
10501037
} else if (liftOnScroll) {
10511038
startLiftOnScrollColorAnimation(
10521039
lifted ? 0 : appBarElevation, lifted ? appBarElevation : 0);
@@ -1058,19 +1045,7 @@ boolean setLiftedState(boolean lifted, boolean force) {
10581045
}
10591046

10601047
private boolean isLiftOnScrollCompatibleBackground() {
1061-
Drawable background = getBackground();
1062-
if (background instanceof MaterialShapeDrawable) {
1063-
return true;
1064-
}
1065-
if (background instanceof LayerDrawable) {
1066-
LayerDrawable layerBackground = (LayerDrawable) background;
1067-
if (layerBackground.getNumberOfLayers() == 2
1068-
&& layerBackground.getDrawable(0) instanceof MaterialShapeDrawable
1069-
&& layerBackground.getDrawable(1) instanceof MaterialShapeDrawable) {
1070-
return true;
1071-
}
1072-
}
1073-
return false;
1048+
return getBackground() instanceof MaterialShapeDrawable;
10741049
}
10751050

10761051
private void startLiftOnScrollColorAnimation(

tests/javatests/com/google/android/material/appbar/AppBarWithToolbarTest.java

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import static org.junit.Assert.assertEquals;
2323

2424
import android.graphics.Rect;
25-
import android.graphics.drawable.LayerDrawable;
2625
import android.view.View;
2726
import android.view.ViewGroup;
2827
import androidx.coordinatorlayout.widget.CoordinatorLayout;
@@ -395,19 +394,11 @@ public void testLiftOnScrollColor() throws Throwable {
395394
final int appbarHeight = mAppBar.getHeight();
396395
final int longSwipeAmount = 3 * appbarHeight / 2;
397396

398-
LayerDrawable background = (LayerDrawable) mAppBar.getBackground();
399-
MaterialShapeDrawable backgroundLayer = (MaterialShapeDrawable) background.getDrawable(0);
400-
MaterialShapeDrawable liftLayer = (MaterialShapeDrawable) background.getDrawable(1);
397+
MaterialShapeDrawable backgroundDrawable = mAppBar.getMaterialShapeBackground();
401398

402399
assertEquals(
403400
mAppBar.getResources().getColor(R.color.material_blue_grey_900),
404-
backgroundLayer.getResolvedTintColor());
405-
assertEquals(
406-
mAppBar.getResources().getColor(R.color.material_blue_grey_950),
407-
liftLayer.getResolvedTintColor());
408-
409-
assertEquals(255, backgroundLayer.getAlpha());
410-
assertEquals(0, liftLayer.getAlpha());
401+
backgroundDrawable.getResolvedTintColor());
411402

412403
// Perform a swipe-up gesture across the horizontal center of the screen.
413404
performVerticalSwipeUpGesture(
@@ -416,7 +407,8 @@ public void testLiftOnScrollColor() throws Throwable {
416407
originalAppbarBottom + 3 * longSwipeAmount / 2,
417408
longSwipeAmount);
418409

419-
assertEquals(0, backgroundLayer.getAlpha());
420-
assertEquals(255, liftLayer.getAlpha());
410+
assertEquals(
411+
mAppBar.getResources().getColor(R.color.material_blue_grey_950),
412+
backgroundDrawable.getResolvedTintColor());
421413
}
422414
}

0 commit comments

Comments
 (0)