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:
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.
Article Contributed By :
|
|
|
2392 Views
|