Android BottomSheet Example in Kotlin

The bottom sheet is a component that slides up from the bottom of the screen to reveal more content. You may have experience bottom sheet in google maps, Uber and many other apps. Let’s develop in this chapter.


There is two kind of bottom sheet, one which we can slide up and down any time; it is called Persistent Bottom Sheet. Another one is Modal Bottom Sheet, which opens from the bottom when some action happens like if we need to share something, options will come from the bottom.


Let’s start the development:
First, let’s create the layout of the part which we need to show on the bottom sheet. We will build a layout file and name it bottom_sheet.xml.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/bottom_sheet_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:behavior_hideable="true"
    app:behavior_peekHeight="56dp"
    app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="This is persistent Bottom Sheet"
        android:textSize="20sp" />
<TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="Welcome to MindOrks!!"
        android:textSize="20sp" />
<TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="Let's Join our Community on Slack"
        android:textSize="18sp" />
<TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="Also follow us on Twitter"
        android:textSize="18sp" />
<Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:background="@android:color/holo_orange_light"
        android:text="Join Slack Community"
        android:textColor="@android:color/white" />
</LinearLayout>

We also need to make the layout which we need to show on the main screen. Here, we will create three buttons


One, to open the persistent bottom sheet. One, to open the Modal bottom sheet as a dialog. And, last one, to open the Modal bottom sheet as a dialog fragment.

<?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">
<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
<Button
            android:id="@+id/btnBottomSheet"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="Bottom Sheet" />
<Button
            android:id="@+id/btnBottomSheetDialog"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="Bottom Sheet Dialog" />
<Button
            android:id="@+id/btnBottomSheetDialogFragment"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="Bottom Sheet Dialog Fragment" />
</LinearLayout>
<include layout="@layout/bottom_sheet" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

Let’s open MainActivity. Here, we will wire up the actions on the BottomSheet. To set the BottomSheet behavior, we need to pass the parent view of our bottom sheet layout.

var bottomSheetBehavior = BottomSheetBehavior.from(bottom_sheet_layout)

Now, we will set the listener to our first button, which will open the persistent bottom sheet.

btnBottomSheet.setOnClickListener {
    if (bottomSheetBehavior.getState() != BottomSheetBehavior.STATE_EXPANDED) {
        bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED)
    } else {
        bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED)
    }
}

Here, we are checking the state of the bottom sheet. If the bottom sheet is not expanded means not fully open, then we will set it to open else collapse it.

We can also handle the different state of the bottomsheet with BottomSheetCallback() methods. To use it we use,

behavior.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
        override fun onStateChanged(bottomSheet: View, newState: Int) {
            // React to state change
            when (newState) {
                BottomSheetBehavior.STATE_HIDDEN -> {
                }
                BottomSheetBehavior.STATE_EXPANDED -> {
                }
                BottomSheetBehavior.STATE_COLLAPSED -> {
                }
                BottomSheetBehavior.STATE_DRAGGING -> {
                }
                BottomSheetBehavior.STATE_SETTLING -> {
                }
            }            }

        override fun onSlide(bottomSheet: View, slideOffset: Float) {
            // React to dragging events
        }
    })
}

Here, STATE_HIDDEN means the bottomsheet is hidden, STATE_EXPANDED means the sheet is in Expanded state and so on.


Let’s run this application here once and test the first button.

Let’s start with the Modal Bottom Sheet. We will create a different layout for Modal Bottom Sheet so that we experience the difference here.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/bottom_sheet_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:behavior_hideable="true"
    app:behavior_peekHeight="56dp"
    app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
   <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="This is Modal Bottom Sheet"
        android:textSize="20sp" />
   <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="Welcome to MindOrks!!"
        android:textSize="20sp" />
   <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="Let's Join our Community on Slack"
        android:textSize="18sp" />
   <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="Also follow us on Twitter"
        android:textSize="18sp" />
   <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:background="@android:color/holo_orange_light"
        android:text="Join Slack Community"
        android:textColor="@android:color/white" />
</LinearLayout>

We need to create a fragment class and extend it with the BottomSheetDialogFragment(), and we will set the layout to it.

class BottomSheetFragment : BottomSheetDialogFragment() {
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View =
            inflater.inflate(R.layout.fragment_bottom_sheet_dialog, container, false)
}

Now, set the listener to the other two buttons.


First, Bottom Sheet Dialog button, which will open this sheet as a dialog and this is cancelable if a user taps anywhere on the screen.

btnBottomSheetDialog.setOnClickListener {
    val view = layoutInflater.inflate(R.layout.fragment_bottom_sheet_dialog, null)
    val dialog = BottomSheetDialog(this)
    dialog.setContentView(view)
    dialog.show()
}

Make the other button to open this sheet as a fragment.

btnBottomSheetDialogFragment.setOnClickListener {
    val bottomSheetFragment = BottomSheetFragment()
    bottomSheetFragment.show(supportFragmentManager, bottomSheetFragment.tag)
}

Let’s run this application and try to click all the three button one at a time. Great!! We had created the BottomSheet.

Try to explore more on this and share us with on our twitter and slack channel.