Quellcode durchsuchen

Fix status bar and navigation bar appearance for bottom sheet dialogs, resolves #1802

Aidan Follestad vor 5 Jahren
Ursprung
Commit
bb30d46e77

+ 38 - 5
bottomsheets/src/main/java/com/afollestad/materialdialogs/bottomsheets/BottomSheet.kt

@@ -16,13 +16,16 @@
 package com.afollestad.materialdialogs.bottomsheets
 
 import android.annotation.SuppressLint
+import android.app.Activity
 import android.content.Context
 import android.graphics.drawable.GradientDrawable
+import android.os.Build.VERSION.SDK_INT
 import android.view.LayoutInflater
 import android.view.View.GONE
 import android.view.ViewGroup
 import android.view.Window
 import android.view.WindowManager.LayoutParams
+import android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
 import androidx.coordinatorlayout.widget.CoordinatorLayout
 import com.afollestad.materialdialogs.DialogBehavior
 import com.afollestad.materialdialogs.LayoutMode
@@ -50,13 +53,21 @@ class BottomSheet(
   private var dialog: MaterialDialog? = null
 
   internal var defaultPeekHeight: Int by notNull()
-  internal var maxPeekheight: Int = -1
+  internal var maxPeekHeight: Int = -1
   private var actualPeekHeight: Int by notNull()
 
+  override fun getThemeRes(isDark: Boolean): Int {
+    return if (isDark) {
+      R.style.MD_Dark_BottomSheet
+    } else {
+      R.style.MD_Light_BottomSheet
+    }
+  }
+
   @SuppressLint("InflateParams")
   override fun createView(
-    context: Context,
-    window: Window,
+    creatingContext: Context,
+    dialogWindow: Window,
     layoutInflater: LayoutInflater,
     dialog: MaterialDialog
   ): ViewGroup {
@@ -70,16 +81,38 @@ class BottomSheet(
     this.bottomSheetView = rootView!!.findViewById(R.id.md_root_bottom_sheet)
     this.buttonsLayout = rootView!!.findViewById(R.id.md_button_layout)
 
-    val (_, windowHeight) = window.windowManager.getWidthAndHeight()
+    val (_, windowHeight) = dialogWindow.windowManager.getWidthAndHeight()
     defaultPeekHeight = (windowHeight * DEFAULT_PEEK_HEIGHT_RATIO).toInt()
     actualPeekHeight = defaultPeekHeight
-    maxPeekheight = windowHeight
+    maxPeekHeight = windowHeight
 
     setupBottomSheetBehavior()
+    if (creatingContext is Activity) {
+      carryOverWindowFlags(
+          dialogWindow = dialogWindow,
+          creatingActivity = creatingContext
+      )
+    }
 
     return rootView!!
   }
 
+  private fun carryOverWindowFlags(
+    dialogWindow: Window,
+    creatingActivity: Activity
+  ) {
+    val activityWindow = creatingActivity.window!!
+    if (SDK_INT >= 19) {
+      dialogWindow.addFlags(FLAG_TRANSLUCENT_STATUS)
+    }
+    if (SDK_INT >= 21) {
+      dialogWindow.apply {
+        statusBarColor = activityWindow.statusBarColor
+        navigationBarColor = activityWindow.navigationBarColor
+      }
+    }
+  }
+
   private fun setupBottomSheetBehavior() {
     bottomSheetBehavior = BottomSheetBehavior.from(bottomSheetView)
         .apply {

+ 2 - 2
bottomsheets/src/main/java/com/afollestad/materialdialogs/bottomsheets/BottomSheets.kt

@@ -69,8 +69,8 @@ fun MaterialDialog.setPeekHeight(
 
   val bottomSheet = (dialogBehavior as BottomSheet)
   val literalOrRes = literal ?: context.resources.getDimensionPixelSize(res!!)
-  val destinationPeekHeight = if (bottomSheet.maxPeekheight > 0) {
-    min(bottomSheet.maxPeekheight, literalOrRes)
+  val destinationPeekHeight = if (bottomSheet.maxPeekHeight > 0) {
+    min(bottomSheet.maxPeekHeight, literalOrRes)
   } else {
     literalOrRes
   }

+ 8 - 0
bottomsheets/src/main/res/values/styles.xml

@@ -1,6 +1,14 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
 
+  <style name="MD_Light.BottomSheet" parent="MD_Light">
+    <item name="android:windowIsFloating">false</item>
+  </style>
+
+  <style name="MD_Dark.BottomSheet" parent="MD_Dark">
+    <item name="android:windowIsFloating">false</item>
+  </style>
+
   <style name="MD_GridItem" parent="@style/MD_ListItem">
     <item name="android:paddingTop">8dp</item>
     <item name="android:paddingBottom">8dp</item>

+ 16 - 4
core/src/main/java/com/afollestad/materialdialogs/DialogBehavior.kt

@@ -24,6 +24,7 @@ import android.view.Window
 import android.view.WindowManager.LayoutParams
 import androidx.annotation.ColorInt
 import androidx.annotation.Px
+import androidx.annotation.StyleRes
 import com.afollestad.materialdialogs.WhichButton.NEGATIVE
 import com.afollestad.materialdialogs.WhichButton.POSITIVE
 import com.afollestad.materialdialogs.actions.getActionButton
@@ -34,10 +35,13 @@ import kotlin.math.min
 
 /** @author Aidan Follestad (@afollestad) */
 interface DialogBehavior {
+  /** Gets the styles.xml theme for the dialog Window. */
+  @StyleRes fun getThemeRes(isDark: Boolean): Int
+
   /** Creates the root layout of the dialog. */
   fun createView(
-    context: Context,
-    window: Window,
+    creatingContext: Context,
+    dialogWindow: Window,
     layoutInflater: LayoutInflater,
     dialog: MaterialDialog
   ): ViewGroup
@@ -78,10 +82,18 @@ interface DialogBehavior {
 
 /** @author Aidan Follestad (@afollestad) */
 object ModalDialog : DialogBehavior {
+  override fun getThemeRes(isDark: Boolean): Int {
+    return if (isDark) {
+      R.style.MD_Dark
+    } else {
+      R.style.MD_Light
+    }
+  }
+
   @SuppressLint("InflateParams")
   override fun createView(
-    context: Context,
-    window: Window,
+    creatingContext: Context,
+    dialogWindow: Window,
     layoutInflater: LayoutInflater,
     dialog: MaterialDialog
   ): ViewGroup {

+ 3 - 4
core/src/main/java/com/afollestad/materialdialogs/MaterialDialog.kt

@@ -29,7 +29,6 @@ import androidx.annotation.DimenRes
 import androidx.annotation.DrawableRes
 import androidx.annotation.Px
 import androidx.annotation.StringRes
-import com.afollestad.materialdialogs.Theme.Companion.inferTheme
 import com.afollestad.materialdialogs.WhichButton.NEGATIVE
 import com.afollestad.materialdialogs.WhichButton.NEUTRAL
 import com.afollestad.materialdialogs.WhichButton.POSITIVE
@@ -55,7 +54,7 @@ typealias DialogCallback = (MaterialDialog) -> Unit
 class MaterialDialog(
   val windowContext: Context,
   val dialogBehavior: DialogBehavior = ModalDialog
-) : Dialog(windowContext, inferTheme(windowContext).styleRes) {
+) : Dialog(windowContext, inferTheme(windowContext, dialogBehavior)) {
 
   /**
    * A named config map, used like tags for extensions.
@@ -101,8 +100,8 @@ class MaterialDialog(
   init {
     val layoutInflater = LayoutInflater.from(windowContext)
     val rootView = dialogBehavior.createView(
-        context = windowContext,
-        window = window!!,
+        creatingContext = windowContext,
+        dialogWindow = window!!,
         layoutInflater = layoutInflater,
         dialog = this
     )

+ 12 - 11
core/src/main/java/com/afollestad/materialdialogs/Theme.kt

@@ -17,19 +17,20 @@ package com.afollestad.materialdialogs
 
 import android.R.attr
 import android.content.Context
+import androidx.annotation.CheckResult
 import androidx.annotation.StyleRes
-import com.afollestad.materialdialogs.utils.MDUtil.resolveColor
 import com.afollestad.materialdialogs.utils.MDUtil.isColorDark
+import com.afollestad.materialdialogs.utils.MDUtil.resolveColor
 
-internal enum class Theme(@StyleRes val styleRes: Int) {
-  LIGHT(R.style.MD_Light),
-  DARK(R.style.MD_Dark);
+@StyleRes @CheckResult
+internal fun inferTheme(
+  context: Context,
+  dialogBehavior: DialogBehavior
+): Int {
+  val isThemeDark = !inferThemeIsLight(context)
+  return dialogBehavior.getThemeRes(isThemeDark)
+}
 
-  companion object {
-    fun inferTheme(context: Context): Theme {
-      val isPrimaryDark =
-        resolveColor(context = context, attr = attr.textColorPrimary).isColorDark()
-      return if (isPrimaryDark) LIGHT else DARK
-    }
-  }
+@CheckResult internal fun inferThemeIsLight(context: Context): Boolean {
+  return resolveColor(context = context, attr = attr.textColorPrimary).isColorDark()
 }

+ 3 - 4
core/src/main/java/com/afollestad/materialdialogs/internal/button/DialogActionButton.kt

@@ -25,8 +25,7 @@ import android.view.Gravity.CENTER
 import androidx.annotation.ColorInt
 import androidx.appcompat.widget.AppCompatButton
 import com.afollestad.materialdialogs.R
-import com.afollestad.materialdialogs.Theme.Companion.inferTheme
-import com.afollestad.materialdialogs.Theme.LIGHT
+import com.afollestad.materialdialogs.inferThemeIsLight
 import com.afollestad.materialdialogs.utils.MDUtil.ifNotZero
 import com.afollestad.materialdialogs.utils.MDUtil.resolveColor
 import com.afollestad.materialdialogs.utils.MDUtil.resolveDrawable
@@ -70,12 +69,12 @@ class DialogActionButton(
     setSupportAllCaps(casing == CASING_UPPER)
 
     // Text color
-    val theme = inferTheme(appContext)
+    val isLightTheme = inferThemeIsLight(appContext)
     enabledColor = resolveColor(appContext, attr = R.attr.md_color_button_text) {
       resolveColor(appContext, attr = R.attr.colorPrimary)
     }
     val disabledColorRes =
-      if (theme == LIGHT) R.color.md_disabled_text_light_theme
+      if (isLightTheme) R.color.md_disabled_text_light_theme
       else R.color.md_disabled_text_dark_theme
     disabledColor = resolveColor(baseContext, res = disabledColorRes)
     setTextColor(enabledColor)

+ 2 - 0
core/src/main/res/values/styles.xml

@@ -8,6 +8,7 @@
 
     <item name="android:actionModeBackground">@color/primary_material_dark</item>
     <item name="android:actionModeCloseDrawable">@drawable/md_nav_back</item>
+    <item name="android:windowNoTitle">true</item>
 
     <item name="android:windowAnimationStyle">@style/MD_WindowAnimation</item>
     <item name="android:backgroundDimEnabled">true</item>
@@ -27,6 +28,7 @@
 
     <item name="android:windowAnimationStyle">@style/MD_WindowAnimation</item>
     <item name="android:backgroundDimEnabled">true</item>
+    <item name="android:windowNoTitle">true</item>
 
     <item name="md_divider_color">@color/md_divider_dark_theme</item>
     <item name="md_item_selector">@drawable/md_item_selector_dark</item>

+ 7 - 6
sample/src/main/java/com/afollestad/materialdialogssample/MainActivity.kt

@@ -33,6 +33,7 @@ import com.afollestad.assent.Permission.READ_EXTERNAL_STORAGE
 import com.afollestad.assent.Permission.WRITE_EXTERNAL_STORAGE
 import com.afollestad.assent.runWithPermissions
 import com.afollestad.materialdialogs.DialogBehavior
+import com.afollestad.materialdialogs.LayoutMode.WRAP_CONTENT
 import com.afollestad.materialdialogs.MaterialDialog
 import com.afollestad.materialdialogs.ModalDialog
 import com.afollestad.materialdialogs.bottomsheets.BasicGridItem
@@ -701,7 +702,7 @@ class MainActivity : AppCompatActivity() {
     }
 
     bottomsheet_info.setOnClickListener {
-      MaterialDialog(this, BottomSheet()).show {
+      MaterialDialog(this, BottomSheet(WRAP_CONTENT)).show {
         title(R.string.useGoogleLocationServices)
         message(R.string.useGoogleLocationServicesPrompt)
         positiveButton(R.string.agree)
@@ -711,7 +712,7 @@ class MainActivity : AppCompatActivity() {
     }
 
     bottomsheet_list.setOnClickListener {
-      MaterialDialog(this, BottomSheet()).show {
+      MaterialDialog(this, BottomSheet(WRAP_CONTENT)).show {
         listItems(R.array.states) { _, index, text ->
           toast("Selected item $text at index $index")
         }
@@ -733,7 +734,7 @@ class MainActivity : AppCompatActivity() {
           BasicGridItem(R.drawable.ic_icon_android, "Eight")
       )
 
-      MaterialDialog(this, BottomSheet()).show {
+      MaterialDialog(this, BottomSheet(WRAP_CONTENT)).show {
         gridItems(items) { _, index, item ->
           toast("Selected item ${item.title} at index $index")
         }
@@ -744,11 +745,11 @@ class MainActivity : AppCompatActivity() {
     }
 
     bottomsheet_customView.setOnClickListener {
-      showCustomViewDialog(BottomSheet())
+      showCustomViewDialog(BottomSheet(WRAP_CONTENT))
     }
 
     bottomsheet_colorPicker.setOnClickListener {
-      MaterialDialog(this, BottomSheet()).show {
+      MaterialDialog(this, BottomSheet(WRAP_CONTENT)).show {
         title(R.string.custom_colors_argb)
         colorChooser(
             colors = ColorPalette.Primary,
@@ -766,7 +767,7 @@ class MainActivity : AppCompatActivity() {
     }
 
     bottomsheet_dateTimePicker.setOnClickListener {
-      MaterialDialog(this, BottomSheet()).show {
+      MaterialDialog(this, BottomSheet(WRAP_CONTENT)).show {
         title(text = "Select Date and Time")
         dateTimePicker(requireFutureDateTime = true) { _, dateTime ->
           toast("Selected date/time: ${dateTime.formatDateTime()}")

+ 12 - 0
sample/src/main/res/values-v21/styles_parent.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+  <style name="ThemeParent" parent="Theme.MaterialComponents.Light.DarkActionBar">
+    <item name="android:navigationBarColor">?colorPrimaryDark</item>
+  </style>
+
+  <style name="ThemeParent.Dark" parent="Theme.MaterialComponents">
+    <item name="android:navigationBarColor">?colorPrimaryDark</item>
+  </style>
+
+</resources>

+ 3 - 3
sample/src/main/res/values/styles.xml

@@ -1,13 +1,13 @@
 <resources xmlns:tools="http://schemas.android.com/tools">
 
   <!-- http://www.google.com/design/spec/style/color.html#color-color-palette -->
-  <style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
+  <style name="AppTheme" parent="ThemeParent">
     <item name="colorPrimary">@color/primary</item>
     <item name="colorPrimaryDark">@color/primaryDark</item>
     <item name="colorAccent">@color/accent</item>
   </style>
 
-  <style name="AppTheme.Dark" parent="Theme.MaterialComponents">
+  <style name="AppTheme.Dark" parent="ThemeParent.Dark">
     <item name="colorPrimary">@color/primary</item>
     <item name="colorPrimaryDark">@color/primaryDark</item>
     <item name="colorAccent">@color/accent</item>
@@ -15,7 +15,7 @@
     <item name="md_button_casing">literal</item>
   </style>
 
-  <style name="AppTheme.Custom" parent="Theme.MaterialComponents.Light">
+  <style name="AppTheme.Custom" parent="ThemeParent">
     <item name="colorPrimary">@color/primary_custom</item>
     <item name="colorPrimaryDark">@color/primaryDark_custom</item>
     <item name="colorAccent">@color/accent_custom</item>

+ 8 - 0
sample/src/main/res/values/styles_parent.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+  <style name="ThemeParent" parent="Theme.MaterialComponents.Light.DarkActionBar"/>
+
+  <style name="ThemeParent.Dark" parent="Theme.MaterialComponents"/>
+
+</resources>