Android BottomSheet

Android BottomSheet Example in Kotlin


Android BottomSheet is a component that slides from the bottom of the screen to reveal more information. You can see Android BottomSheet in action in Google Maps android app.

Google Map Persistent BottomSheet

In this tutorial we will learn about the types of BottomSheet and how you can integrate it in your Android application using Kotlin.

Types of Android BottomSheet

  1. Standard BottomSheet or Persistent BottomSheet: This type of BottomSheet remains visible at the bottom along with the primary screen. User can interact with the sheet like sliding it up and down to reveal or hide content.
  2. Modal BottomSheet: This type of sheet opens from the bottom when user performs any action for example showing the sharing option when tap on share button.

Bottom sheets have 5 states:

  • STATE_COLLAPSED: The bottom sheet is visible but only showing its peek height. This state is usually the ‘resting position’ of a Bottom Sheet. The peek height is chosen by the developer and should be enough to indicate there is extra content, allow the user to trigger an action or expand the bottom sheet.
  • STATE_EXPANDED: The bottom sheet is visible and its maximum height and it is neither dragging or settling (see below).
  • STATE_DRAGGING: The user is actively dragging the bottom sheet up or down.
  • STATE_SETTLING: The bottom sheet is settling to 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.

Source: material.io

Adding BottomSheet in Android Application

Let’s create a new Empty Android Project.

In build.gradle file add the latest support design dependency:

implementation 'com.android.support:design:28.0.0'

We will first start with Persistent Bottom Sheet:

Add a new layout file as persistent_bottom_sheet.xml in the project. This file will contain the layout of the persistent bottom sheet.

<?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/persistent_bottom_sheet"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#FFFFFF"
    android:orientation="vertical"
    app:behavior_hideable="true"
    app:behavior_peekHeight="56dp"
    app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">

    <TextView
        android:id="@+id/textView3"
        android:layout_width="match_parent"
        android:layout_height="26dp"
        android:layout_marginTop="0dp"
        android:background="#E8E5E5"
        android:gravity="bottom|center_horizontal"
        android:text="—"
        android:textAlignment="center"
        android:textSize="30sp" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:layout_marginStart="0dp"
        android:layout_marginEnd="0dp"
        android:background="#E8E5E5"
        android:gravity="center|top"
        android:text="Explore Persistent Bottom Sheet"
        android:textAlignment="center"
        android:textSize="18sp"
        android:textStyle="bold" />

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#3FBCED"
        android:text="Follow us on Twitter @mobiraft"
        android:textColor="#FFFFFF"
        android:textSize="18sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/textView4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Mobiraft.com"
        android:textAlignment="center"
        android:textColor="#344CE3"
        android:textSize="50sp" />
</LinearLayout>

Now let’s go to our activity_main.xml file. Here we will add 3 buttons to show different bottomSheet examples and link our persistent_bottom_sheet.xml file.

<?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="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
        <Button
            android:id="@+id/persistentBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="Persistent Bottom Sheet" />    </LinearLayout>
    <include layout="@layout/persistent_bottom_sheet" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

If you run the application at this point you will be able to see the persistent BottomSheet in action. Now we will bind our persistent bottom sheet with the button we have added and change our button text on the sheet state change.

In your MainActivity.kt file add a variable of type BottomSheetBehavior and pass our persistent_bottom_sheet layout

private lateinit var bottomSheetBehavior: BottomSheetBehavior<LinearLayout>

bottomSheetBehavior = BottomSheetBehavior.from<LinearLayout>(persistent_bottom_sheet)

Let’s add bottomSheet callback to observe bottom sheet states:

bottomSheetBehavior.setBottomSheetCallback(object: BottomSheetBehavior.BottomSheetCallback(){
            override fun onStateChanged(bottomSheet: View, state: Int) {
                print(state)
                when (state) {

                    BottomSheetBehavior.STATE_HIDDEN -> {
                        persistentBtn.text = "Show Bottom Sheet"
                    }
                    BottomSheetBehavior.STATE_EXPANDED ->
                        persistentBtn.text = "Close Bottom Sheet"
                    BottomSheetBehavior.STATE_COLLAPSED ->
                        persistentBtn.text = "Show Bottom Sheet"
                    BottomSheetBehavior.STATE_DRAGGING -> {
                    }
                    BottomSheetBehavior.STATE_SETTLING -> {
                    }
                    BottomSheetBehavior.STATE_HALF_EXPANDED -> {

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

To toggle between expand and close state of the sheet we will add click listener to our persistentBtn.

persistentBtn.setOnClickListener(View.OnClickListener {
  expandCollapseSheet()
})

 private fun expandCollapseSheet() {
        if (bottomSheetBehavior.state != BottomSheetBehavior.STATE_EXPANDED) {
            bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
            persistentBtn.text = "Close Bottom Sheet"
        } else {
            bottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
            persistentBtn.text = "Show Bottom Sheet"
        }
    }

So far, your application will look like this:

Persistent BottomSheet

Let’s proceed to our other type of Bottom Sheet i.e. Modal BottomSheet

We will create a different layout to showcase Modal BottomSheet. Lets call our new layout as fragment_modal_bottom_sheet.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="wrap_content">

    <TextView
        android:id="@+id/textView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="Hello Modal BottomSheet"
        android:textAlignment="center"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="#3FBCED"
        android:text="Follow us on Twitter @mobiraft"
        android:textColor="#FFFFFF"
        android:textSize="18sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

    <Button
        android:id="@+id/button3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="#2E64D1"
        android:text="Hello Mobiraft"
        android:textColor="#FFFFFF"
        android:textSize="18sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button2" />
</androidx.constraintlayout.widget.ConstraintLayout>

Add 2 more buttons in your activity_main.xml file, one to show Modal BottomSheet using dialog and other to show Modal BottomSheet using fragment.

To show the Modal BottomSheet as fragment lets add a fragment class and bind it with the new layout we just created(you can create a new layout for the fragment, for this demo we will show the same layout for the dialog and the fragment).

class ModalBottomSheet : BottomSheetDialogFragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_modal_bottom_sheet, container, false)
    }
}

Lets wire up our newly added button to show Modal Bottom Sheet. Navigate to your MainActivity.kt

bottomSheetDialogBtn.setOnClickListener{
            val modalSheetView = layoutInflater.inflate(R.layout.fragment_modal_bottom_sheet,null)
            val dialog = BottomSheetDialog(this)
            dialog.setContentView(modalSheetView)
            dialog.show()

        }

        bottomSheetDialogFragmentBtn.setOnClickListener {
            val modalbottomSheetFragment = ModalBottomSheet()
            modalbottomSheetFragment.show(supportFragmentManager,modalbottomSheetFragment.tag)
        }

Here is our Modal BottomSheet in action:

Modal Bottom Sheet

You can checkout the complete project on Github

Interested in how to get started with Kotlin Multiplatform, check out our tutorial: https://mobiraft.com/android/kotlin/getting-started-with-kotlin-multiplatform/


Like it? Share with your friends!

0 Comments

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