How to implement BottomSheetDialog Fragment in Android using Kotlin.

Last updated Jan 12, 2022

In this android example, you will see how to implement BottomSheetDialog Fragment in Android using Kotlin. BottomSheet Dialog is The Android BottomSheet component glides down from the bottom of the screen to provide additional information. In the Google Maps android app, you can see Android BottomSheet in action.

Types of Android BottomSheet:

1.  Persistent BottomSheet: 
The primary screen and this type of BottomSheet stay visible at the bottom. The sheet can be manipulated by the user by sliding it up and down to reveal or hide content.
2.  Modal BottomSheet: When a user performs a specific action, such as tapping on the share button, this sort of page opens from the bottom.

 

Bottom sheets have 5 states:

STATE_COLLAPSED

STATE_EXPANDED

STATE_DRAGGING

STATE_SETTLING

STATE_HIDDEN

 

Implementation of Bottom Sheet Dialog Fragment:

Step 1.
Create a new Project in android studio.

Go to File > New > New Project > Empty Activity > Next > Enter Name > Select Language Kotlin > Finish.

 

Step 2. Create a new Fragment and add the following

app > java > package name > right-click > New > Fragment > Fragment(Blank) > enter name (ModalBottomSheet) > FINISH.

 

Step 3. Open activity_main.xml file and add create a design by adding the following code:

<?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"
    android:background="#EFE8E8"
    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" />

        <Button
            android:id="@+id/bottomSheetDialogFragmentBtn"
            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/persistent_bottom_sheet" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

 

Step 4. Open fragment_modal_bottom_sheet.xml file and add the following xml code:

<?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:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="Example of Modal BottomSheet"
        android:textAlignment="center"
        android:textSize="24sp"
        android:gravity="center"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher">
    </ImageView>
    <Button
        android:id="@+id/button2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#C0E4F3"
        android:text="Hi Developers"
        android:textAllCaps="false"
        android:textColor="#000000"
        android:textSize="18sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />
</LinearLayout>

 

Step 5. Go to ModalBottomSheet.kt file and the code be like:

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)
    }
}

 

Step 6. Create a new layout resource file and add the following code 

app > res > layout > new > layout resource file > enter name (persistent_bottom_sheet) > ok

Code:

<?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="Example of  Persistent Bottom Sheet"
        android:textAlignment="center"
        android:textSize="18sp"
        android:textStyle="bold" />

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher">
    </ImageView>
    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#B5E0F1"
        android:text="Hi Developers"
        android:textColor="#000"
        android:textAllCaps="false"
        android:textSize="18sp"
        android:textStyle="bold" />

</LinearLayout>

 

Step 7. Finally, Open MainActivity.kt file

Create the variable of buttons and bottomSheetBehavior
 

    private lateinit var bottomSheetBehavior: BottomSheetBehavior
    lateinit var persistentBtn: Button
    lateinit var bottomSheetDialogFragmentBtn: Button

 

Instantiate the variables by using its id and add below setContentView(R.layout.activity_main)
 

 

persistentBtn = findViewById(R.id.persistentBtn)
bottomSheetDialogFragmentBtn=findViewById(R.id.bottomSheetDialogFragmentBtn)
val bottomSheet = findViewById(R.id.persistent_bottom_sheet)
bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet)

 

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) {
            }
        })

 

Create a new private function which holds the state of collapsing the dialog

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"
        }
    }

 

Set onClickListener on button by using:

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

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

 

Final code of MainActivity:

class MainActivity : AppCompatActivity() {

    private lateinit var bottomSheetBehavior: BottomSheetBehavior
    lateinit var persistentBtn: Button
    lateinit var bottomSheetDialogFragmentBtn: Button


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        persistentBtn = findViewById(R.id.persistentBtn)
        bottomSheetDialogFragmentBtn = findViewById(R.id.bottomSheetDialogFragmentBtn)
        val bottomSheet = findViewById(R.id.persistent_bottom_sheet)
        bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet)

        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) {
            }
        })

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

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

    }
    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"
        }
    }

}

 

Step 8. Now run the app in your emulator, and get the following output.

Output:
 

BottomSheetDialog

 

 

BottomSheetDialog

 

 

 

BottomSheetDialog

 

 

 

Complete source code of Bottom Sheet Dialog Fragment with Example:

activity_main.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"
    android:background="#EFE8E8"
    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" />

        <Button
            android:id="@+id/bottomSheetDialogFragmentBtn"
            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/persistent_bottom_sheet" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

 

MainActivity.kt file

import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.LinearLayout
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.bottomsheet.BottomSheetBehavior

class MainActivity : AppCompatActivity() {

    private lateinit var bottomSheetBehavior: BottomSheetBehavior
    lateinit var persistentBtn: Button
    lateinit var bottomSheetDialogFragmentBtn: Button


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        persistentBtn = findViewById(R.id.persistentBtn)
        bottomSheetDialogFragmentBtn = findViewById(R.id.bottomSheetDialogFragmentBtn)
        val bottomSheet = findViewById(R.id.persistent_bottom_sheet)
        bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet)

        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) {
            }
        })

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

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

    }
    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"
        }
    }

}

 

persistent_bottom_sheet.xml  file

<?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="Example of  Persistent Bottom Sheet"
        android:textAlignment="center"
        android:textSize="18sp"
        android:textStyle="bold" />

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher">
    </ImageView>
    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#B5E0F1"
        android:text="Hi Developers"
        android:textColor="#000"
        android:textAllCaps="false"
        android:textSize="18sp"
        android:textStyle="bold" />


</LinearLayout>

 

fragment_modal_bottom_sheet.xml file

<?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:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="Example of Modal BottomSheet"
        android:textAlignment="center"
        android:textSize="24sp"
        android:gravity="center"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher">
    </ImageView>
    <Button
        android:id="@+id/button2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#C0E4F3"
        android:text="Hi Developers"
        android:textAllCaps="false"
        android:textColor="#000000"
        android:textSize="18sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />
</LinearLayout>

 

ModalBottomSheet.kt file

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.android.material.bottomsheet.BottomSheetDialogFragment

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)
    }
}

 

Conclusion: In this article we have covered how to implement Bottom Sheet Dialog Fragment in Android Using Kotlin.

 

Download Source code

 

<?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"
    android:background="#EFE8E8"
    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" />

        <Button
            android:id="@+id/bottomSheetDialogFragmentBtn"
            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/persistent_bottom_sheet" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

 

Step 4. Open fragment_modal_bottom_sheet.xml file and add the following xml code:

<?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:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="Example of Modal BottomSheet"
        android:textAlignment="center"
        android:textSize="24sp"
        android:gravity="center"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher">
    </ImageView>
    <Button
        android:id="@+id/button2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#C0E4F3"
        android:text="Hi Developers"
        android:textAllCaps="false"
        android:textColor="#000000"
        android:textSize="18sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />
</LinearLayout>

 

Step 5. Go to ModalBottomSheet.kt file and the code be like:

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)
    }
}

 

Step 6. Create a new layout resource file and add the following code 

app > res > layout > new > layout resource file > enter name (persistent_bottom_sheet) > ok

Code:

<?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="Example of  Persistent Bottom Sheet"
        android:textAlignment="center"
        android:textSize="18sp"
        android:textStyle="bold" />

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher">
    </ImageView>
    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#B5E0F1"
        android:text="Hi Developers"
        android:textColor="#000"
        android:textAllCaps="false"
        android:textSize="18sp"
        android:textStyle="bold" />

</LinearLayout>

 

Step 7. Finally, Open MainActivity.kt file

Create the variable of buttons and bottomSheetBehavior
 

    private lateinit var bottomSheetBehavior: BottomSheetBehavior
    lateinit var persistentBtn: Button
    lateinit var bottomSheetDialogFragmentBtn: Button

 

Instantiate the variables by using its id and add below setContentView(R.layout.activity_main)
 

 

persistentBtn = findViewById(R.id.persistentBtn)
bottomSheetDialogFragmentBtn=findViewById(R.id.bottomSheetDialogFragmentBtn)
val bottomSheet = findViewById(R.id.persistent_bottom_sheet)
bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet)

 

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) {
            }
        })

 

Create a new private function which holds the state of collapsing the dialog

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"
        }
    }

 

Set onClickListener on button by using:

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

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

 

Final code of MainActivity:

class MainActivity : AppCompatActivity() {

    private lateinit var bottomSheetBehavior: BottomSheetBehavior
    lateinit var persistentBtn: Button
    lateinit var bottomSheetDialogFragmentBtn: Button


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        persistentBtn = findViewById(R.id.persistentBtn)
        bottomSheetDialogFragmentBtn = findViewById(R.id.bottomSheetDialogFragmentBtn)
        val bottomSheet = findViewById(R.id.persistent_bottom_sheet)
        bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet)

        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) {
            }
        })

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

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

    }
    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"
        }
    }

}

 

Step 8. Now run the app in your emulator, and get the following output.

Output:
 

BottomSheetDialog

 

 

BottomSheetDialog

 

 

 

BottomSheetDialog

 

 

 

Complete source code of Bottom Sheet Dialog Fragment with Example:

activity_main.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"
    android:background="#EFE8E8"
    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" />

        <Button
            android:id="@+id/bottomSheetDialogFragmentBtn"
            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/persistent_bottom_sheet" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

 

MainActivity.kt file

import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.LinearLayout
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.bottomsheet.BottomSheetBehavior

class MainActivity : AppCompatActivity() {

    private lateinit var bottomSheetBehavior: BottomSheetBehavior
    lateinit var persistentBtn: Button
    lateinit var bottomSheetDialogFragmentBtn: Button


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        persistentBtn = findViewById(R.id.persistentBtn)
        bottomSheetDialogFragmentBtn = findViewById(R.id.bottomSheetDialogFragmentBtn)
        val bottomSheet = findViewById(R.id.persistent_bottom_sheet)
        bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet)

        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) {
            }
        })

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

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

    }
    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"
        }
    }

}

 

persistent_bottom_sheet.xml  file

<?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="Example of  Persistent Bottom Sheet"
        android:textAlignment="center"
        android:textSize="18sp"
        android:textStyle="bold" />

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher">
    </ImageView>
    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#B5E0F1"
        android:text="Hi Developers"
        android:textColor="#000"
        android:textAllCaps="false"
        android:textSize="18sp"
        android:textStyle="bold" />


</LinearLayout>

 

fragment_modal_bottom_sheet.xml file

<?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:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="Example of Modal BottomSheet"
        android:textAlignment="center"
        android:textSize="24sp"
        android:gravity="center"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher">
    </ImageView>
    <Button
        android:id="@+id/button2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#C0E4F3"
        android:text="Hi Developers"
        android:textAllCaps="false"
        android:textColor="#000000"
        android:textSize="18sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />
</LinearLayout>

 

ModalBottomSheet.kt file

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.android.material.bottomsheet.BottomSheetDialogFragment

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)
    }
}

 

Conclusion: In this article we have covered how to implement Bottom Sheet Dialog Fragment in Android Using Kotlin.

 

Download Source code

 

-->
Article Contributed By :
https://www.rrtutors.com/site_assets/profile/assets/img/avataaars.svg

1797 Views