Guide To Setup Material Bottom Sheets In Android With Example

Android Bottom Sheet is the Android Materiel Design Components that slide up from the bottom of the screen. Also, part of the material design components. Bottom sheets are displayed as a result of the user-triggered action, and also it can reveal additional content by swiping up.

Already, I have explained some of the material components in detail. check below,

Sliders — Material Component For Android

ShapeableImageView — Material Components For Android

Navigation rail – Material Component For Android

Types of Bottom Sheets

There are two types of Bottom Sheets available on android:

Persistent bottom sheets

Persistent bottom sheets collapse
Persistent bottom sheets expand

BottomSheetBehavior is applied to a child of CoordinatorLayout to make that child a persistent bottom sheet.

The Persistent bottom sheets display in-app content. It will be displayed at the bottom of the screen making some portion of the content visible.

Modal Bottom Sheets

Modal Bottom Sheets

slides up from the bottom of the screen to reveal more content. It’s a dialog that is an alternative to content choosers, simple menus, or dialog. Used to present deep-linked content from other apps.

Let’s see both bottom sheets in detail.

Persistent bottom sheets with example

As mentioned above, the bottom sheets are part of the android material design library. Make sure you have included the library in your project.

implementation 'com.google.android.material:material:1.2.0'

BottomSheetBehavior is a type of layout_behavior used for persistent bottom sheets. It requires setting CoordinatorLayout as the root element of that layout.

<?xml version="1.0" encoding="utf-8"?>
    <androidx.coordinatorlayout.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity"
        android:background="@android:color/darker_gray">

        <include layout="@layout/layout_persistent_bottomsheet"/>
    </androidx.coordinatorlayout.widget.CoordinatorLayout>

Adding the XML attribute app:layout_behavior:android.support.design.widget.BottomSheetBehavior to the child view.

<androidx.constraintlayout.widget.ConstraintLayout 
        android:id="@+id/bottomSheet"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/white"
        app:behavior_hideable="false"
        app:behavior_peekHeight="50dp"
        app:behavior_skipCollapsed="true"
        app:layout_behavior="@string/bottom_sheet_behavior"/>

attributes

behavior_peekHeight — The initial “peek” (collapsed state) height of the sheet. The default value is auto, which sets the peak height at the 16:9 ratio keyline of the parent container.

behavior_hideable — Determines whether or not the sheet can be hidden when using a drag-down gesture. The default value is false for Standard Bottom Sheets and true for Modal Bottom Sheets.

behavior_draggable — Determines whether or not the sheet can be collapsed/expanded when using a drag gesture. The default value is true.

behavior_skipCollapsed — Determines whether or not the collapsed state should be ignored when hiding the sheet. This has no effect if behavior_hideable is not set to true. The default value is false.

Setting bottom sheet attributes programmatically

val standardBottomSheetBehavior = BottomSheetBehavior.from(bottomSheet) standardBottomSheetBehavior.isHideable = false standardBottomSheetBehavior.peekHeight = 50 standardBottomSheetBehavior.isDraggable = true standardBottomSheetBehavior.skipCollapsed = false

The bottom sheet states:

The bottom sheets have 5 states,
STATE_COLLAPSED — The bottom sheet is visible but only shows its peak height.

Bottom sheet STATE_COLLAPSED

STATE_EXPANDED — The bottom sheet is visible and its maximum height and it is neither dragging nor settling (see below).

bottom sheet STATE_EXPANDED

STATE_DRAGGING — The sheet can be collapsed/expanded when using a drag gesture.

STATE_SETTLING — The bottom sheet is settling to a specific height after a drag/swipe gesture. This will be the peek height, expanded height, or 0, in case the user action caused the bottom sheet to hide.

STATE_HIDDEN — The bottom sheet is no longer visible.

STATE_HALF_EXPANDED — The sheet is half-expanded (only applicable if behavior_fitToContents has been set to false).

changing the bottom sheets state programmatically,

val standardBottomSheetBehavior = BottomSheetBehavior.from(bottomSheet)
            standardBottomSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN
            //or
            standardBottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
            //or
            standardBottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
            //or
            standardBottomSheetBehavior.state = BottomSheetBehavior.STATE_DRAGGING
            //or
            standardBottomSheetBehavior.state = BottomSheetBehavior.STATE_SETTLING
            //or
            standardBottomSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN
            //or
            standardBottomSheetBehavior.state = BottomSheetBehavior.STATE_HALF_EXPANDED

Handling bottom sheets callbacks

val standardBottomSheetBehavior = BottomSheetBehavior.from(bottomSheet)

            standardBottomSheetBehavior.addBottomSheetCallback(object : BottomSheetCallback() {

                override fun onSlide(bottomSheet: View, slideOffset: Float) {

                }

                override fun onStateChanged(bottomSheet: View, newState: Int) {

                }
            })

In the onStateChanged callback, the newState parameter will be the current state of the bottom sheets.

In the onSlide callback, the slideOffset parameter is a Float value in the [-1.0, 1.0] range. The hidden state is -1.0, the collapsed state is 0.0 and the expanded state is 1.0. The value interpolates linearly and increases as the sheet move upwards.

Modal Bottom Sheets with example

Modal Bottom Sheets are not part of the view layout like Persistent sheets. Instead, they will be shown dynamically using BottomSheetDialog or BottomSheetDialogFragment.

Before creating our BottomSheetDialogFragment however, let’s create the layout for the dialog.

layout_modal_bottomsheet.xml

<?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools">

        <androidx.appcompat.widget.AppCompatTextView
            android:id="@+id/textCreateNew"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            android:text="Create new"
            style="@style/TextAppearance.AppCompat.Large"
            android:layout_margin="8dp"/>

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            app:layout_constraintTop_toBottomOf="@+id/textCreateNew"
            app:layout_constraintStart_toStartOf="parent"
            tools:listitem="@layout/adapter_create_new"
            tools:itemCount="7"
            app:spanCount="3"
            app:layoutManager="androidx.recyclerview.widget.GridLayoutManager" />

    </androidx.constraintlayout.widget.ConstraintLayout>

design for this XML:

Model layout design

I am using recyclerview to display all the items in the bottom sheets dialog fragment.

I have explained recyclerview in detail in another post.

Recyclerview Android Example

We need to create a class that inherits from BottomSheetDialogFragment.

Let’s create MyBottomSheetDialogFragment with recyclerview.

class MyBottomSheetDialogFragment : BottomSheetDialogFragment() {

        override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            return inflater.inflate(R.layout.layout_modal_bottomsheet, container, false)
        }

        override fun onActivityCreated(savedInstanceState: Bundle?) {
            super.onActivityCreated(savedInstanceState)

            val items = mutableListOf<Item>()
            items.add(Item("Folder",R.drawable.ic_baseline_create_new_folder_24))
            items.add(Item("File",R.drawable.ic_baseline_insert_drive_file_24))
            items.add(Item("Photo",R.drawable.ic_baseline_add_a_photo_24))
            items.add(Item("Post",R.drawable.ic_baseline_post_add_24))
            items.add(Item("Poll",R.drawable.ic_baseline_poll_24))
            items.add(Item("Group",R.drawable.ic_baseline_group_add_24))
            items.add(Item("Alarm",R.drawable.ic_baseline_alarm_add_24))
            items.add(Item("Library",R.drawable.ic_baseline_library_add_24))

            recyclerview.layoutManager = GridLayoutManager(context, 3)
            val adapter = RecyclerviewAdapter(items)
            recyclerview.adapter = adapter

        }
    }

Showing a modal bottom sheets

To show a modal bottom sheet, create a MyBottomSheetDialogFragment instance and call the show() method on that class.

MyBottomSheetDialogFragment().apply {
                    show(supportFragmentManager, tag)
                }

Note that we did not set the behavior for the modal sheet to be hideable, nor did we set the peek height. The modal bottom sheet automatically computes appropriate values for both peek height and expanded height.

You can download this example on GITHUB.

Conclusion

Thanks for reading.

Please share if you like it. Also, don’t forget to share your feedback in the comments.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *


Latest Posts