Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[DatePicker] Always go edge-to-edge in fullscreen mode
Resolves #1966 PiperOrigin-RevId: 432296692
- Loading branch information
Showing
6 changed files
with
199 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
152 changes: 152 additions & 0 deletions
152
lib/java/com/google/android/material/internal/EdgeToEdgeUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
/* | ||
* Copyright (C) 2022 The Android Open Source Project | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package com.google.android.material.internal; | ||
|
||
import static android.graphics.Color.TRANSPARENT; | ||
import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP; | ||
import static com.google.android.material.color.MaterialColors.isColorLight; | ||
|
||
import android.annotation.TargetApi; | ||
import android.content.Context; | ||
import android.graphics.Color; | ||
import android.os.Build.VERSION; | ||
import android.os.Build.VERSION_CODES; | ||
import android.view.Window; | ||
import androidx.annotation.ColorInt; | ||
import androidx.annotation.NonNull; | ||
import androidx.annotation.Nullable; | ||
import androidx.annotation.RestrictTo; | ||
import androidx.core.graphics.ColorUtils; | ||
import androidx.core.view.WindowCompat; | ||
import androidx.core.view.WindowInsetsControllerCompat; | ||
import com.google.android.material.color.MaterialColors; | ||
|
||
/** | ||
* A util class that helps apply edge-to-edge mode to activity/dialog windows. | ||
* | ||
* @hide | ||
*/ | ||
@RestrictTo(LIBRARY_GROUP) | ||
public class EdgeToEdgeUtils { | ||
private static final int EDGE_TO_EDGE_BAR_ALPHA = 128; | ||
|
||
private EdgeToEdgeUtils() {} | ||
|
||
/** | ||
* Applies or removes edge-to-edge mode to the provided {@link Window}. When edge-to-edge mode is | ||
* applied, the activities, or the non-floating dialogs, that host the provided window will be | ||
* drawn over the system bar area by default and the system bar colors will be adjusted according | ||
* to the background color you provide. | ||
*/ | ||
public static void applyEdgeToEdge(@NonNull Window window, boolean edgeToEdgeEnabled) { | ||
applyEdgeToEdge(window, edgeToEdgeEnabled, null, null); | ||
} | ||
|
||
/** | ||
* Applies or removes edge-to-edge mode to the provided {@link Window}. When edge-to-edge mode is | ||
* applied, the activities, or the non-floating dialogs, that host the provided window will be | ||
* drawn over the system bar area by default and the system bar colors will be adjusted according | ||
* to the background color you provide. | ||
* | ||
* @param statusBarOverlapBackgroundColor The reference background color to decide the text/icon | ||
* colors on status bars. {@code null} to use the default color from | ||
* {@code ?android:attr/colorBackground}. | ||
* @param navigationBarOverlapBackgroundColor The reference background color to decide the icon | ||
* colors on navigation bars.{@code null} to use the default color from | ||
* {@code ?android:attr/colorBackground}. | ||
*/ | ||
public static void applyEdgeToEdge( | ||
@NonNull Window window, | ||
boolean edgeToEdgeEnabled, | ||
@Nullable @ColorInt Integer statusBarOverlapBackgroundColor, | ||
@Nullable @ColorInt Integer navigationBarOverlapBackgroundColor) { | ||
if (VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) { | ||
return; | ||
} | ||
|
||
// If the overlapping background color is unknown or TRANSPARENT, use the default one. | ||
boolean useDefaultBackgroundColorForStatusBar = | ||
statusBarOverlapBackgroundColor == null || statusBarOverlapBackgroundColor == 0; | ||
boolean useDefaultBackgroundColorForNavigationBar = | ||
navigationBarOverlapBackgroundColor == null || navigationBarOverlapBackgroundColor == 0; | ||
if (useDefaultBackgroundColorForStatusBar || useDefaultBackgroundColorForNavigationBar) { | ||
int defaultBackgroundColor = | ||
MaterialColors.getColor(window.getContext(), android.R.attr.colorBackground, Color.BLACK); | ||
if (useDefaultBackgroundColorForStatusBar) { | ||
statusBarOverlapBackgroundColor = defaultBackgroundColor; | ||
} | ||
if (useDefaultBackgroundColorForNavigationBar) { | ||
navigationBarOverlapBackgroundColor = defaultBackgroundColor; | ||
} | ||
} | ||
|
||
WindowCompat.setDecorFitsSystemWindows(window, !edgeToEdgeEnabled); | ||
|
||
int statusBarColor = getStatusBarColor(window.getContext(), edgeToEdgeEnabled); | ||
int navigationBarColor = getNavigationBarColor(window.getContext(), edgeToEdgeEnabled); | ||
|
||
window.setStatusBarColor(statusBarColor); | ||
window.setNavigationBarColor(navigationBarColor); | ||
|
||
boolean isLightStatusBar = | ||
isUsingLightSystemBar(statusBarColor, isColorLight(statusBarOverlapBackgroundColor)); | ||
boolean isLightNavigationBar = | ||
isUsingLightSystemBar( | ||
navigationBarColor, isColorLight(navigationBarOverlapBackgroundColor)); | ||
|
||
WindowInsetsControllerCompat insetsController = | ||
WindowCompat.getInsetsController(window, window.getDecorView()); | ||
if (insetsController != null) { | ||
insetsController.setAppearanceLightStatusBars(isLightStatusBar); | ||
insetsController.setAppearanceLightNavigationBars(isLightNavigationBar); | ||
} | ||
} | ||
|
||
@TargetApi(VERSION_CODES.LOLLIPOP) | ||
private static int getStatusBarColor(Context context, boolean isEdgeToEdgeEnabled) { | ||
if (isEdgeToEdgeEnabled && VERSION.SDK_INT < VERSION_CODES.M) { | ||
// Light status bars are only supported on M+. So we need to use a translucent black status | ||
// bar instead to ensure the text/icon contrast of it. | ||
int opaqueStatusBarColor = | ||
MaterialColors.getColor(context, android.R.attr.statusBarColor, Color.BLACK); | ||
return ColorUtils.setAlphaComponent(opaqueStatusBarColor, EDGE_TO_EDGE_BAR_ALPHA); | ||
} | ||
if (isEdgeToEdgeEnabled) { | ||
return TRANSPARENT; | ||
} | ||
return MaterialColors.getColor(context, android.R.attr.statusBarColor, Color.BLACK); | ||
} | ||
|
||
@TargetApi(VERSION_CODES.LOLLIPOP) | ||
private static int getNavigationBarColor(Context context, boolean isEdgeToEdgeEnabled) { | ||
// Light navigation bars are only supported on O_MR1+. So we need to use a translucent black | ||
// navigation bar instead to ensure the text/icon contrast of it. | ||
if (isEdgeToEdgeEnabled && VERSION.SDK_INT < VERSION_CODES.O_MR1) { | ||
int opaqueNavBarColor = | ||
MaterialColors.getColor(context, android.R.attr.navigationBarColor, Color.BLACK); | ||
return ColorUtils.setAlphaComponent(opaqueNavBarColor, EDGE_TO_EDGE_BAR_ALPHA); | ||
} | ||
if (isEdgeToEdgeEnabled) { | ||
return TRANSPARENT; | ||
} | ||
return MaterialColors.getColor(context, android.R.attr.navigationBarColor, Color.BLACK); | ||
} | ||
|
||
private static boolean isUsingLightSystemBar(int systemBarColor, boolean isLightBackground) { | ||
return isColorLight(systemBarColor) || (systemBarColor == TRANSPARENT && isLightBackground); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters