From be6050a23c773d93469eb5b4cfa26a2a908f6269 Mon Sep 17 00:00:00 2001 From: conradchen Date: Thu, 3 Mar 2022 18:20:26 -0500 Subject: [PATCH] [DatePicker] Always go edge-to-edge in fullscreen mode Resolves https://github.com/material-components/material-components-android/issues/1966 PiperOrigin-RevId: 432296692 --- .../WindowPreferencesManager.java | 80 +-------- .../datepicker/MaterialDatePicker.java | 31 ++++ .../layout/mtrl_picker_header_fullscreen.xml | 1 + .../material/datepicker/res/values/themes.xml | 2 + .../material/internal/EdgeToEdgeUtils.java | 152 ++++++++++++++++++ .../android/material/internal/ViewUtils.java | 11 ++ 6 files changed, 199 insertions(+), 78 deletions(-) create mode 100644 lib/java/com/google/android/material/internal/EdgeToEdgeUtils.java diff --git a/catalog/java/io/material/catalog/windowpreferences/WindowPreferencesManager.java b/catalog/java/io/material/catalog/windowpreferences/WindowPreferencesManager.java index c67c8950546..fe011c60c0e 100644 --- a/catalog/java/io/material/catalog/windowpreferences/WindowPreferencesManager.java +++ b/catalog/java/io/material/catalog/windowpreferences/WindowPreferencesManager.java @@ -16,34 +16,18 @@ package io.material.catalog.windowpreferences; -import static android.graphics.Color.TRANSPARENT; -import static android.view.View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; -import static android.view.View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; -import static android.view.View.SYSTEM_UI_FLAG_VISIBLE; -import static com.google.android.material.color.MaterialColors.isColorLight; - -import android.annotation.TargetApi; import android.content.Context; import android.content.SharedPreferences; -import android.graphics.Color; import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; -import android.view.View; import android.view.Window; -import androidx.annotation.RequiresApi; -import androidx.core.graphics.ColorUtils; -import com.google.android.material.color.MaterialColors; +import com.google.android.material.internal.EdgeToEdgeUtils; /** Helper that saves the current window preferences for the Catalog. */ public class WindowPreferencesManager { private static final String PREFERENCES_NAME = "window_preferences"; private static final String KEY_EDGE_TO_EDGE_ENABLED = "edge_to_edge_enabled"; - private static final int EDGE_TO_EDGE_BAR_ALPHA = 128; - - @RequiresApi(VERSION_CODES.LOLLIPOP) - private static final int EDGE_TO_EDGE_FLAGS = - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE; private final Context context; @@ -66,67 +50,7 @@ public boolean isEdgeToEdgeEnabled() { @SuppressWarnings("RestrictTo") public void applyEdgeToEdgePreference(Window window) { - if (VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) { - return; - } - boolean edgeToEdgeEnabled = isEdgeToEdgeEnabled(); - - int statusBarColor = getStatusBarColor(isEdgeToEdgeEnabled()); - int navbarColor = getNavBarColor(isEdgeToEdgeEnabled()); - - boolean lightBackground = - isColorLight(MaterialColors.getColor(context, android.R.attr.colorBackground, Color.BLACK)); - boolean lightStatusBar = isColorLight(statusBarColor); - boolean showDarkStatusBarIcons = - lightStatusBar || (statusBarColor == TRANSPARENT && lightBackground); - boolean lightNavbar = isColorLight(navbarColor); - boolean showDarkNavbarIcons = lightNavbar || (navbarColor == TRANSPARENT && lightBackground); - - View decorView = window.getDecorView(); - int currentStatusBar = - showDarkStatusBarIcons && VERSION.SDK_INT >= VERSION_CODES.M - ? SYSTEM_UI_FLAG_LIGHT_STATUS_BAR - : 0; - int currentNavBar = - showDarkNavbarIcons && VERSION.SDK_INT >= VERSION_CODES.O - ? SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR - : 0; - - window.setNavigationBarColor(navbarColor); - window.setStatusBarColor(statusBarColor); - int systemUiVisibility = (edgeToEdgeEnabled ? EDGE_TO_EDGE_FLAGS : SYSTEM_UI_FLAG_VISIBLE) - | currentStatusBar - | currentNavBar; - - decorView.setSystemUiVisibility(systemUiVisibility); - } - - @SuppressWarnings("RestrictTo") - @TargetApi(VERSION_CODES.LOLLIPOP) - private int getStatusBarColor(boolean isEdgeToEdgeEnabled) { - if (isEdgeToEdgeEnabled && VERSION.SDK_INT < VERSION_CODES.M) { - 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); - } - - @SuppressWarnings("RestrictTo") - @TargetApi(VERSION_CODES.LOLLIPOP) - private int getNavBarColor(boolean isEdgeToEdgeEnabled) { - 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); + EdgeToEdgeUtils.applyEdgeToEdge(window, isEdgeToEdgeEnabled()); } private SharedPreferences getSharedPreferences() { diff --git a/lib/java/com/google/android/material/datepicker/MaterialDatePicker.java b/lib/java/com/google/android/material/datepicker/MaterialDatePicker.java index e9253b3e882..aa31ce7525f 100644 --- a/lib/java/com/google/android/material/datepicker/MaterialDatePicker.java +++ b/lib/java/com/google/android/material/datepicker/MaterialDatePicker.java @@ -49,9 +49,13 @@ import androidx.annotation.StringRes; import androidx.annotation.StyleRes; import androidx.core.util.Pair; +import androidx.core.view.OnApplyWindowInsetsListener; import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; import com.google.android.material.dialog.InsetDialogOnTouchListener; import com.google.android.material.internal.CheckableImageButton; +import com.google.android.material.internal.EdgeToEdgeUtils; +import com.google.android.material.internal.ViewUtils; import com.google.android.material.resources.MaterialAttributes; import com.google.android.material.shape.MaterialShapeDrawable; import java.lang.annotation.Retention; @@ -303,6 +307,7 @@ public void onStart() { if (fullscreen) { window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); window.setBackgroundDrawable(background); + enableEdgeToEdge(window); } else { window.setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); int inset = @@ -351,6 +356,32 @@ public final S getSelection() { return getDateSelector().getSelection(); } + private void enableEdgeToEdge(Window window) { + final View headerLayout = requireView().findViewById(R.id.fullscreen_header); + EdgeToEdgeUtils.applyEdgeToEdge( + window, true, ViewUtils.getBackgroundColor(headerLayout), null); + final int originalPaddingTop = headerLayout.getPaddingTop(); + final int originalHeaderHeight = headerLayout.getLayoutParams().height; + ViewCompat.setOnApplyWindowInsetsListener( + headerLayout, + new OnApplyWindowInsetsListener() { + @Override + public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) { + int topInset = insets.getInsets(WindowInsetsCompat.Type.systemBars()).top; + if (originalHeaderHeight >= 0) { + headerLayout.getLayoutParams().height = originalHeaderHeight + topInset; + headerLayout.setLayoutParams(headerLayout.getLayoutParams()); + } + headerLayout.setPadding( + headerLayout.getPaddingLeft(), + originalPaddingTop + topInset, + headerLayout.getPaddingRight(), + headerLayout.getPaddingBottom()); + return insets; + } + }); + } + private void updateHeader() { String headerText = getHeaderText(); headerSelectionText.setContentDescription( diff --git a/lib/java/com/google/android/material/datepicker/res/layout/mtrl_picker_header_fullscreen.xml b/lib/java/com/google/android/material/datepicker/res/layout/mtrl_picker_header_fullscreen.xml index 9011392aabd..fa2ddbdeedf 100644 --- a/lib/java/com/google/android/material/datepicker/res/layout/mtrl_picker_header_fullscreen.xml +++ b/lib/java/com/google/android/material/datepicker/res/layout/mtrl_picker_header_fullscreen.xml @@ -21,6 +21,7 @@ android:layout_height="@dimen/mtrl_calendar_header_height_fullscreen"> @@ -80,6 +81,7 @@