3434import android .graphics .Canvas ;
3535import android .graphics .Rect ;
3636import android .graphics .drawable .ColorDrawable ;
37+ import android .graphics .drawable .ColorStateListDrawable ;
3738import android .graphics .drawable .Drawable ;
3839import android .os .Build ;
3940import android .os .Build .VERSION ;
5152import android .widget .ScrollView ;
5253import androidx .annotation .ColorInt ;
5354import androidx .annotation .Dimension ;
55+ import androidx .annotation .DoNotInline ;
5456import androidx .annotation .DrawableRes ;
5557import androidx .annotation .IdRes ;
5658import androidx .annotation .IntDef ;
@@ -234,7 +236,7 @@ public AppBarLayout(@NonNull Context context, @Nullable AttributeSet attrs, int
234236 context = getContext ();
235237 setOrientation (VERTICAL );
236238
237- if (Build . VERSION .SDK_INT >= 21 ) {
239+ if (VERSION .SDK_INT >= 21 ) {
238240 // Use the bounds view outline provider so that we cast a shadow, even without a
239241 // background
240242 if (getOutlineProvider () == ViewOutlineProvider .BACKGROUND ) {
@@ -256,10 +258,10 @@ public AppBarLayout(@NonNull Context context, @Nullable AttributeSet attrs, int
256258 MaterialResources .getColorStateList (
257259 context , a , R .styleable .AppBarLayout_liftOnScrollColor );
258260
259- if ( getBackground () instanceof ColorDrawable ) {
260- ColorDrawable background = ( ColorDrawable ) getBackground ();
261+ ColorStateList backgroundCSL = getBackgroundCSL ();
262+ if ( backgroundCSL != null ) {
261263 MaterialShapeDrawable materialShapeDrawable = new MaterialShapeDrawable ();
262- materialShapeDrawable .setFillColor (ColorStateList . valueOf ( background . getColor ()) );
264+ materialShapeDrawable .setFillColor (backgroundCSL );
263265 // If there is a lift on scroll color specified, we do not initialize the elevation overlay
264266 // and set the alpha to zero manually.
265267 if (liftOnScrollColor != null ) {
@@ -283,12 +285,12 @@ public AppBarLayout(@NonNull Context context, @Nullable AttributeSet attrs, int
283285 /* force */ false );
284286 }
285287
286- if (Build . VERSION .SDK_INT >= 21 && a .hasValue (R .styleable .AppBarLayout_elevation )) {
288+ if (VERSION .SDK_INT >= 21 && a .hasValue (R .styleable .AppBarLayout_elevation )) {
287289 ViewUtilsLollipop .setDefaultAppBarLayoutStateListAnimator (
288290 this , a .getDimensionPixelSize (R .styleable .AppBarLayout_elevation , 0 ));
289291 }
290292
291- if (Build . VERSION .SDK_INT >= Build . VERSION_CODES .O ) {
293+ if (VERSION .SDK_INT >= VERSION_CODES .O ) {
292294 // In O+, we have these values set in the style. Since there is no defStyleAttr for
293295 // AppBarLayout at the AppCompat level, check for these attributes here.
294296 if (a .hasValue (R .styleable .AppBarLayout_android_keyboardNavigationCluster )) {
@@ -321,6 +323,17 @@ public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets)
321323 });
322324 }
323325
326+ @ Nullable
327+ private ColorStateList getBackgroundCSL () {
328+ Drawable background = getBackground ();
329+ if (background instanceof ColorDrawable ) {
330+ return ColorStateList .valueOf (((ColorDrawable ) background ).getColor ());
331+ } else if (VERSION .SDK_INT >= VERSION_CODES .Q ) {
332+ return DrawableHelperV29 .maybeGetBackgroundCSL (background );
333+ }
334+ return null ;
335+ }
336+
324337 private void initializeLiftOnScrollWithColor (MaterialShapeDrawable background ) {
325338 background .setAlpha (lifted ? 255 : 0 );
326339 background .setFillColor (liftOnScrollColor );
@@ -2555,4 +2568,16 @@ public void onOffsetChanged(
25552568 }
25562569 }
25572570 }
2571+
2572+ @ RequiresApi (VERSION_CODES .Q )
2573+ private static class DrawableHelperV29 {
2574+ @ DoNotInline
2575+ @ Nullable
2576+ private static ColorStateList maybeGetBackgroundCSL (@ Nullable Drawable background ) {
2577+ if (background instanceof ColorStateListDrawable ) {
2578+ return ((ColorStateListDrawable ) background ).getColorStateList ();
2579+ }
2580+ return null ;
2581+ }
2582+ }
25582583}
0 commit comments