Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Rounded modal bottom sheet as seen in new Google products(Tasks, News, etc.), described in this article: https://medium.com/halcyon-mobile/implementing-googles-refreshed-modal-bottom-sheet-4e76cb5de65b
<!-- Drawable used for the bottom sheet dialog background -->
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:topLeftRadius="@dimen/bottom_sheet_corner_radius"
android:topRightRadius="@dimen/bottom_sheet_corner_radius" />
<padding android:top="@dimen/bottom_sheet_top_padding" />
<solid android:color="@color/primary" />
</shape>
<dimen name="bottom_sheet_corner_radius">16dp</dimen>
<dimen name="bottom_sheet_top_padding">8dp</dimen>
package com.your.package
import android.app.Dialog
import android.os.Bundle
import com.your.package.R
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
/**
* BottomSheetDialog fragment that uses a custom
* theme which sets a rounded background to the dialog
* and doesn't dim the navigation bar
*/
open class RoundedBottomSheetDialogFragment : BottomSheetDialogFragment() {
override fun getTheme(): Int = R.style.BottomSheetDialogTheme
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = BottomSheetDialog(requireContext(), theme)
}
<!-- v21 styles, you can merge these two if your minSdkVersion is >= 21 -->
<resources>
<style name="BottomSheetDialogTheme" parent="BaseBottomSheetDialog">
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@color/white</item>
</style>
</resources>
<resources>
<!-- set the rounded drawable as background to your bottom sheet -->
<style name="BottomSheet" parent="@style/Widget.Design.BottomSheet.Modal">
<item name="android:background">@drawable/bg_bottom_sheet_dialog_fragment</item>
</style>
<style name="BaseBottomSheetDialog" parent="@style/Theme.Design.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="bottomSheetStyle">@style/BottomSheet</item>
</style>
<style name="BottomSheetDialogTheme" parent="BaseBottomSheetDialog" />
</resources>
@JoaquimLey

This comment has been minimized.

Copy link

@JoaquimLey JoaquimLey commented May 26, 2018

Hey, how about you include a link to your article here? :) keep those traffic loops working :)

@luca992

This comment has been minimized.

Copy link

@luca992 luca992 commented May 30, 2018

In your article.

You show a white navigation bar with dark icons.

How did you get that?
Did you specify
<item name="android:windowLightNavigationBar">true</item>
In your app theme?

@ArthurNagy

This comment has been minimized.

Copy link
Owner Author

@ArthurNagy ArthurNagy commented Jul 5, 2018

Hey @JoaquimLey good idea, thanks!

@luca992 sorry, didn't get any notification about your comment, to answer your question, yes, I'm using:
<item name="android:windowLightNavigationBar">true</item> in my v27 AppTheme

@benhaxe

This comment has been minimized.

Copy link

@benhaxe benhaxe commented Aug 27, 2018

Hey,
Can you please share the link to the full project am very new to this & Kotlin

@RankoR

This comment has been minimized.

Copy link

@RankoR RankoR commented Nov 14, 2018

This does not work when using MaterialComponents theme.

@ExploiTR

This comment has been minimized.

Copy link

@ExploiTR ExploiTR commented Dec 1, 2018

Seems only kotlin here

@dima-ostapovets

This comment has been minimized.

Copy link

@dima-ostapovets dima-ostapovets commented Dec 7, 2018

Is it possible to customize bottomsheet slide animation (e.q. duration) using BottomSheet style?

@ldavidsp

This comment has been minimized.

Copy link

@ldavidsp ldavidsp commented Jan 12, 2019

MenuBinding no found for my in kotlin.

@rafaelkowal

This comment has been minimized.

Copy link

@rafaelkowal rafaelkowal commented Jan 17, 2019

How to run the bottom sheet using btn.setOnClickListener in the normal version would I call bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED, as would this in your example?

@fiskurgit

This comment has been minimized.

Copy link

@fiskurgit fiskurgit commented Mar 20, 2019

Change background opacity as you scroll the dialog:

open class RoundedBottomSheetDialogFragment : BottomSheetDialogFragment() {

    override fun getTheme(): Int = R.style.BottomSheetDialogTheme

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val dialog = BottomSheetDialog(requireContext(), theme)

        dialog.setOnShowListener {
            dialog.behavior.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
                override fun onStateChanged(bottomSheet: View, newState: Int) {
                    if (newState == BottomSheetBehavior.STATE_HIDDEN) {
                        dialog.dismiss()
                    }
                }

                override fun onSlide(bottomSheet: View, slideOffset: Float) {
                    if(!slideOffset.isNaN()) dialog.window?.setDimAmount(0.5f - ((slideOffset * -1)/2))
                }
            })
        }

        return dialog
    }
}
@coddicted

This comment has been minimized.

Copy link

@coddicted coddicted commented Mar 27, 2019

How to do MenuBinding in Java?
I want to design bottomsheet like one used in whatsapp for status views. Any idea how to achieve that?

@Morteza-Rastgoo

This comment has been minimized.

Copy link

@Morteza-Rastgoo Morteza-Rastgoo commented May 12, 2019

Crashes on API < 21

android.view.InflateException: Binary XML file line #40: Error inflating class

@EdricChan03

This comment has been minimized.

Copy link

@EdricChan03 EdricChan03 commented May 17, 2019

@benhaxe The source code for the actual app is here (although the design has since been revamped): https://github.com/ArthurNagy/WorkoutLog

If you want the old design, view the repository before the new redesign here: https://github.com/ArthurNagy/WorkoutLog/tree/762125a91aeee0c0b6443d8aad6681659f8a5960

@AlienAsRoger

This comment has been minimized.

Copy link

@AlienAsRoger AlienAsRoger commented May 30, 2019

Thanks for opening project, but I think there are some parts that missing

File google-services.json is missing. The Google Services Plugin cannot function without it. 

I can understand why it was taken out, but was curios if you could include a dummy one so people can at least run the project. Thank you!

@Secretbox1987

This comment has been minimized.

Copy link

@Secretbox1987 Secretbox1987 commented Jun 4, 2019

When app returning from background, dialog hide and re show quickly. Do you know how fix it?

@ArthurNagy

This comment has been minimized.

Copy link
Owner Author

@ArthurNagy ArthurNagy commented Jun 30, 2019

Thanks for opening project, but I think there are some parts that missing

File google-services.json is missing. The Google Services Plugin cannot function without it. 

I can understand why it was taken out, but was curios if you could include a dummy one so people can at least run the project. Thank you!

Hey, I think it will work if you add your own google-services.json file. Just create a dummy Firebase project and generate the file. AlthoughI haven't been able to work on the project, so nothing fancy to see there 😢

@wax911

This comment has been minimized.

Copy link

@wax911 wax911 commented Sep 24, 2019

Alternatively if you don't want to include a google-service.json file you could simply refactor the app build.gradle file to

if (file("google-services.json").exists()) {
    apply plugin: 'com.google.gms.google-services'
}

This just allows the project to build

@cakfan

This comment has been minimized.

Copy link

@cakfan cakfan commented Dec 1, 2019

Not working when using MaterialComponent theme

@ArthurNagy

This comment has been minimized.

Copy link
Owner Author

@ArthurNagy ArthurNagy commented Dec 1, 2019

Hey @cakfan! As I mentioned in my article, there's no reason to use this implementation with MaterialComponents since there is an easier solution using ShapeTheming.

@NurseyitTursunkulov

This comment has been minimized.

Copy link

@NurseyitTursunkulov NurseyitTursunkulov commented Mar 23, 2020

add full source code! :(

@bamsbamx

This comment has been minimized.

Copy link

@bamsbamx bamsbamx commented Mar 30, 2020

Just like this with the new API

<!-- Stuff to make the bottom sheet with round top borders -->
<style name="BottomSheetShapeAppearance" parent="ShapeAppearance.MaterialComponents.LargeComponent">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSizeTopLeft">12dp</item>
    <item name="cornerSizeTopRight">12dp</item>
</style>

<style name="BottomSheet" parent="@style/Widget.Design.BottomSheet.Modal">
    <item name="shapeAppearance">@style/BottomSheetShapeAppearance</item>
</style>

<style name="BaseBottomSheetMenu" parent="@style/Theme.Design.Light.BottomSheetDialog">
    <item name="android:windowIsFloating">false</item>
    <item name="bottomSheetStyle">@style/BottomSheet</item>
</style>

<style name="BottomSheetMenuTheme" parent="@style/BaseBottomSheetMenu" />
@bamsbamx

This comment has been minimized.

Copy link

@bamsbamx bamsbamx commented Mar 30, 2020

Change background opacity as you scroll the dialog:

open class RoundedBottomSheetDialogFragment : BottomSheetDialogFragment() {

    override fun getTheme(): Int = R.style.BottomSheetDialogTheme

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val dialog = BottomSheetDialog(requireContext(), theme)

        dialog.setOnShowListener {
            dialog.behavior.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
                override fun onStateChanged(bottomSheet: View, newState: Int) {
                    if (newState == BottomSheetBehavior.STATE_HIDDEN) {
                        dialog.dismiss()
                    }
                }

                override fun onSlide(bottomSheet: View, slideOffset: Float) {
                    if(!slideOffset.isNaN()) dialog.window?.setDimAmount(0.5f - ((slideOffset * -1)/2))
                }
            })
        }

        return dialog
    }
}

setBottomSheetCallback is now deprecated, you can use addBottomSheetCallback now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.