Material-components-android: BottomSheetDialogFragment bottom navigation color

Created on 17 Jan 2019  ·  12Comments  ·  Source: material-components/material-components-android

I have tried to apply a custom color to the bottom navigation bar but failed.
I tried this:

<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:windowLightNavigationBar">true</item>
<item name="android:navigationBarColor">@color/white</item>
<item name="android:windowTranslucentNavigation">false</item>

It works for usual DialogFragment but not for the BottomSheetDialogFragment.

I tried this also:

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val dialog = super.onCreateDialog(savedInstanceState) as BottomSheetDialog
        dialog.setOnShowListener { dialogInterface ->
            val d = dialogInterface as BottomSheetDialog
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                d.window?.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
                d.window?.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
                d.window?.navigationBarColor = ContextCompat.getColor(requireContext(), R.color.white)
            }
        }

        return dialog 
}

How can I change the nagivation bar color to custom? Right now it is always transparent.

Most helpful comment

My solution for this is by having my own bottom sheet style and applying it by overriding the getTheme() method:

    <style name="Widget.AppTheme.BottomSheet" parent="Theme.MaterialComponents.Light.BottomSheetDialog">
        <item name="android:windowIsFloating">false</item> <!-- This is important -->
        <item name="android:statusBarColor">@color/transparent</item> <!-- And then this will be needed -->
        <item name="android:navigationBarColor">@color/bottom_sheet_background</item>
        <item name="android:colorBackground">@color/bottom_sheet_background</item>
    </style>

I'm yet to try making the navbar transparent and making the actual bottom sheet draws under the navbar, but that one is working for now.

All 12 comments

@Zeliret Did you manage to figure this one out, by chance? No matter what I do, I still get the transparency on top of my usually white navigation, which looks pretty wonky. Tried everything in the above Medium article, too 🤷‍♂️

My solution for this is by having my own bottom sheet style and applying it by overriding the getTheme() method:

    <style name="Widget.AppTheme.BottomSheet" parent="Theme.MaterialComponents.Light.BottomSheetDialog">
        <item name="android:windowIsFloating">false</item> <!-- This is important -->
        <item name="android:statusBarColor">@color/transparent</item> <!-- And then this will be needed -->
        <item name="android:navigationBarColor">@color/bottom_sheet_background</item>
        <item name="android:colorBackground">@color/bottom_sheet_background</item>
    </style>

I'm yet to try making the navbar transparent and making the actual bottom sheet draws under the navbar, but that one is working for now.

@ivaniskandar Big thx! You save my time :)

This needs to be fixed!

Also facing this issue.

Experiencing this issue as well.

+1

thanks @ivaniskandar , it worked!

<style name="ThemeOverlay.MyTheme.BottomSheetDialog" parent="ThemeOverlay.MaterialComponents.Light.BottomSheetDialog">
        <item name="android:windowIsFloating">false</item>
        <item name="android:windowLightNavigationBar" tools:targetApi="o_mr1">true</item>
        <item name="android:navigationBarColor">?colorSurface</item>
        <item name="android:navigationBarDividerColor" tools:targetApi="o_mr1">?colorSurface</item>
    </style>

Any idea how to have bottom navigation bar white transparent like system share dialog? I mean we can see a bit of content behind navigation bar while scrolling?

I tried
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
but this does nothing

@SamYStudiO You can use this Kotlin extension:

import android.graphics.Color
import android.os.Build.VERSION.SDK_INT
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.annotation.RequiresApi
import androidx.core.view.marginTop
import androidx.core.view.marginBottom
import androidx.core.view.updateLayoutParams
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.R as MdcR

fun BottomSheetDialog.drawBelowSystemUi(viewInDialog: View) {
    if (SDK_INT < 21) return // Unsupported

    // We are not using padding but margin because using padding hasn't been successful.
    // See this request: https://github.com/chrisbanes/insetter/issues/66

    // We defer getting the initial margin to avoid retrieving it before the view is added,
    // where the LayoutParams that contain the margin values would not be there yet.

    val initialTopMargin by layz(NONE) { viewInDialog.marginTop }
    val initialBottomMargin by lazy(NONE) { viewInDialog.marginBottom }

    viewInDialog.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
        @RequiresApi(21)
        override fun onViewAttachedToWindow(v: View) {
            val designBottomSheet = findViewById<FrameLayout>(MdcR.id.design_bottom_sheet)!!
            designBottomSheet.setBackgroundColor(Color.TRANSPARENT)
            designBottomSheet.setOnApplyWindowInsetsListener { _, insets ->
                viewInDialog.updateLayoutParams<ViewGroup.MarginLayoutParams> {
                    topMargin = initialTopMargin + insets.systemWindowInsetTop
                    bottomMargin = initialBottomMargin + insets.systemWindowInsetBottom
                }
                insets.consumeSystemWindowInsets()
            }
            val container = window!!.peekDecorView().findViewById<ViewGroup>(MdcR.id.container)!!
            container.fitsSystemWindows = false
        }

        override fun onViewDetachedFromWindow(v: View?) = Unit
    })
}

There's no need to override an entire theme, or change any of your Java/Kotlin code. Just set the appropriate theme overlay in your app theme:

<style
    name="MyAppTheme"
    parent="Theme.MaterialComponents.DayNight"
>
    …
    <item name="bottomSheetDialogTheme">@style/MyAppBottomSheetDialog</item>
    …
</style>

<style
    name="MyAppBottomSheetDialog"
    parent="@style/ThemeOverlay.MaterialComponents.BottomSheetDialog"
>
    <item name="android:windowIsFloating">false</item>
</style>
Was this page helpful?
0 / 5 - 0 ratings