Android Bottom Sheet

Google introduce many new components like Bottom Sheet, Navigation View,  Floating Label Edittext, Floating Action Button, Snackbar, Collapsing toolbar in design support library which are very useful for android developers. In this blog we are going to work with Android Bottom Sheet. Bottom Sheet is component which slide up from the bottom for displaying more information or for displaying options. We can see real time use of bottom sheet in Google Map application where location information , direction information shows in bottom sheet.

BottomSheet like Google Map

What are the types of Bottom Sheet?

There are two types of Bottom Sheets.

1. Persistent Bottom Sheet:

> Persistent Bottom Sheet is view in same activity/fragment which is currently visible on screen. As we have discuss before we can see efficient use of Persistent Botton Sheet in Google Map app where it used for displaying more informations regarding direction and location.

2. Modal Bottom Sheet:

> Modal Bottom Sheet is also a part of a same view which is currently visible on the screen. But we are showing them dynamically using BottomSheetDialog or BottomSheetDialogFragment. We can see efficient use of Modal Bottom Sheet in Google Drive app or when we use sharing intent in our application. Generally Modal Bottom Sheet is use for displaying deep linked contents.

How to integrate Persistent Bottom Sheet?

1. Open build.gradle and add latest support design dependency.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/bottomSheet"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/white"
    app:behavior_hideable="true"
    app:behavior_peekHeight="56dp"
    app:layout_behavior="android.support.design.widget.BottomSheetBehavior">

    <TextView
        android:id="@+id/textViewFacebook"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fontFamily="sans-serif"
        android:padding="16dp"
        android:gravity="center_vertical"
        android:drawablePadding="16dp"
        android:drawableLeft="@drawable/ico_facebook"
        android:drawableStart="@drawable/ico_facebook"
        android:text="Facebook"
        android:textSize="16sp" />

    <View
        android:id="@+id/facebookView"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#bdbdbd"
        app:layout_constraintTop_toBottomOf="@id/textViewFacebook" />

    <TextView
        android:id="@+id/textViewTwitter"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fontFamily="sans-serif"
        android:padding="16dp"
        android:text="Twitter"
        android:gravity="center_vertical"
        android:drawablePadding="16dp"
        android:drawableLeft="@drawable/ico_twitter"
        android:drawableStart="@drawable/ico_twitter"
        android:textSize="16sp"
        app:layout_constraintTop_toBottomOf="@id/facebookView" />

    <View
        android:id="@+id/twitterView"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#bdbdbd"
        app:layout_constraintTop_toBottomOf="@id/textViewTwitter" />

    <TextView
        android:id="@+id/textViewInstagram"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fontFamily="sans-serif"
        android:padding="16dp"
        android:gravity="center_vertical"
        android:drawablePadding="16dp"
        android:drawableLeft="@drawable/ico_instagram"
        android:drawableStart="@drawable/ico_instagram"
        android:text="Instagram"
        android:textSize="16sp"
        app:layout_constraintTop_toBottomOf="@id/twitterView" />

    <View
        android:id="@+id/instagramView"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#bdbdbd"
        app:layout_constraintTop_toBottomOf="@id/textViewInstagram" />

    <TextView
        android:id="@+id/textViewLinkedin"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fontFamily="sans-serif"
        android:padding="16dp"
        android:gravity="center_vertical"
        android:drawablePadding="16dp"
        android:drawableLeft="@drawable/ico_linkedin"
        android:drawableStart="@drawable/ico_linkedin"
        android:text="Linkedin"
        android:textSize="16sp"
        app:layout_constraintTop_toBottomOf="@id/instagramView" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#bdbdbd"
        app:layout_constraintTop_toBottomOf="@id/textViewLinkedin" />

</android.support.constraint.ConstraintLayout>


app:behavior_hideable: Make bottom sheet hidden when swipe it down.

app:behavior_peekHeight: This is the height of the bottom sheet when it is minimized (STATE_COLLAPSED). If we want to make some part of bottom sheet visible than we need to set this property.
app:layout_behavior: We need set this behavior property when we need to make layout act as bottom sheet.

3. Now open activity_main.xml and add below code. As we have discuss persistent bottom sheet view is a part of visible activity / fragment. so we are going to include bottom_sheet_layout.xml into activity_main.xml.

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.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:id="@+id/coordinateBottomSheet"
    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">

        <android.support.v7.widget.Toolbar
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/colorPrimary"
            app:title="BottomSheet Demo"
            app:titleTextColor="@android:color/white" />

        <Button
            android:id="@+id/buttonSlideUp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginEnd="10dp"
            android:layout_marginStart="10dp"
            android:text="Slide Up" />

        <Button
            android:id="@+id/buttonBottomSheetDialog"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginEnd="10dp"
            android:layout_marginStart="10dp"
            android:text="BottomSheet Dialog" />

        <Button
            android:id="@+id/buttonBottomSheetDialogFragment"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginEnd="10dp"
            android:layout_marginStart="10dp"
            android:text="BottomSheet Dialog Fragment" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:fontFamily="sans-serif"
            android:gravity="center_horizontal"
            android:text="Welcome To Android4Dev"
            android:textColor="@color/colorPrimary"
            android:textSize="22sp"
            android:textStyle="bold"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </LinearLayout>

    <include layout="@layout/bottom_sheet_layout" />

</android.support.design.widget.CoordinatorLayout>

 

4. Open MainActivity.java and add below code.

 

package com.android4dev.bottomsheet

import android.os.Bundle
import android.support.constraint.ConstraintLayout
import android.support.design.widget.BottomSheetBehavior
import android.view.View
import android.widget.Toast
import com.android4dev.bottomsheet.base.BaseActivity
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.bottom_sheet_layout.*


class MainActivity : BaseActivity(), View.OnClickListener {

    private lateinit var bottomSheetBehavior: BottomSheetBehavior<ConstraintLayout>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initView()
    }

    private fun initView() {
        buttonSlideUp.setOnClickListener(this)

        textViewFacebook.setOnClickListener {
            Toast.makeText(this, "Facebook", Toast.LENGTH_SHORT).show()
        }
        textViewTwitter.setOnClickListener {
            Toast.makeText(this, "Twitter", Toast.LENGTH_SHORT).show()
        }
        textViewInstagram.setOnClickListener {
            Toast.makeText(this, "Instagram", Toast.LENGTH_SHORT).show()
        }
        textViewLinkedin.setOnClickListener {
            Toast.makeText(this, "Linkedin", Toast.LENGTH_SHORT).show()
        }
        bottomSheetBehavior = BottomSheetBehavior.from<ConstraintLayout>(bottomSheet)
        bottomSheetBehavior.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
            override fun onSlide(bottomSheet: View, slideOffset: Float) {

            }

            override fun onStateChanged(bottomSheet: View, newState: Int) {
                when (newState) {
                    BottomSheetBehavior.STATE_COLLAPSED -> {
                        buttonSlideUp.text = "Slide Up"
                    }
                    BottomSheetBehavior.STATE_HIDDEN -> {

                    }
                    BottomSheetBehavior.STATE_EXPANDED -> {
                        buttonSlideUp.text = "Slide Down"
                    }
                    BottomSheetBehavior.STATE_DRAGGING -> {

                    }
                    BottomSheetBehavior.STATE_SETTLING -> {

                    }
                }
            }
        })
    }

    override fun onClick(clickView: View?) {
        when (clickView) {
            buttonSlideUp -> {
                slideUpDownBottomSheet()
            }
        }
    }

    /***
     * Manually Slide up and Slide Down
     */
    private fun slideUpDownBottomSheet() {
        if (bottomSheetBehavior.state != BottomSheetBehavior.STATE_EXPANDED) {
            bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
            buttonSlideUp.text = "Slide Down";
        } else {
            bottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED;
            buttonSlideUp.text = "Slide Up"
        }
    }
    
}

BottomSheetBehavior : It provides call back and make bottom sheet work with coordinate layout.
BottomSheetBehavior.BottomSheetCallback() : It sends events when bottom sheet change it’s state. Below are the list of state.

  •  STATE_COLLAPSED : We get this state when the bottom sheet is collapsed.
  •  STATE_DRAGGING : We get this state when the bottom sheet is dragging.
  •  STATE_EXPANDED : We get this state when the bottom sheet is expanded.
  •  STATE_HIDDEN : We get this state when the bottom sheet is hidden.
  •  STATE_SETTLING : We get this state when the bottom sheet is settling.


slideUpDownBottomSheet() : This method will slideup and slidedown bottomsheet when user click on button.

Modal BottomSheet Using BottomSheetDialog and BottomSheetDialogFragment

As we have already discuss Modal Bottom Sheet is also a part of a same view which is currently visible on the screen. But we are showing them dynamically using BottomSheetDialog or BottomSheetDialogFragment. We can see efficient use of Modal Bottom Sheet in Google Drive app or when we use sharing intent in our application. Generally Modal Bottom Sheet is use for displaying deep linked contents.

1. As we have already created bottom_sheet_layout.xml . We are going to reuse it for integrate modal bottom sheet.
2. Create one class name it as BottomSheetFragment  and extends it with BottomSheetDialogFragment and add below code.

package com.android4dev.bottomsheet

import android.os.Bundle
import android.support.design.widget.BottomSheetDialogFragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import kotlinx.android.synthetic.main.bottom_sheet_layout.*

class BottomSheetFragment() : BottomSheetDialogFragment() {

    private var fragmentView: View? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

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

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initView()
    }

    private fun initView() {
        textViewFacebook.setOnClickListener {
            Toast.makeText(context, "Facebook", Toast.LENGTH_SHORT).show()
        }
        textViewTwitter.setOnClickListener {
            Toast.makeText(context, "Twitter", Toast.LENGTH_SHORT).show()
        }
        textViewInstagram.setOnClickListener {
            Toast.makeText(context, "Instagram", Toast.LENGTH_SHORT).show()
        }
        textViewLinkedin.setOnClickListener {
            Toast.makeText(context, "Linkedin", Toast.LENGTH_SHORT).show()
        }
    }
}


3. Now open MainActivity.java and add below method.

private fun showBottomSheetDialogFragment() {
        val bottomSheetFragment = BottomSheetFragment()
        bottomSheetFragment.show(supportFragmentManager, bottomSheetFragment.tag)
    }

Now make one button click and call showBottomSheetDialogFragment() method you will see BottomSheet Side from bottom and also look likes Dialog effect.

4. For BottomSheetDialog add below method in MainActivity.java .

private fun showBottomSheetDialog() {
        val view = layoutInflater.inflate(R.layout.bottom_sheet_layout, null)
        val dialog = BottomSheetDialog(this)
        dialog.setContentView(view)
        view.textViewFacebook.setOnClickListener {
            Toast.makeText(this, "Facebook", Toast.LENGTH_SHORT).show()
        }
        view.textViewTwitter.setOnClickListener {
            Toast.makeText(this, "Twitter", Toast.LENGTH_SHORT).show()
        }
        view.textViewInstagram.setOnClickListener {
            Toast.makeText(this, "Instagram", Toast.LENGTH_SHORT).show()
        }
        view.textViewLinkedin.setOnClickListener {
            Toast.makeText(this, "Linkedin", Toast.LENGTH_SHORT).show()
        }
        dialog.show()
    }

Now make one button click and call showBottomSheetDialog() method you will see BottomSheet Side from bottom and also look likes Dialog effect.

Android BottomSheet

 

Source Code

Demo For Android BottomSheet

For Learning Kotlin Please Refer

How to start with kotlin?

 

https://android4dev.com

Hi, I am Android Developer and Founder of Android4Dev. Right now my interest is in RxKotlin, MVVM and Dagger2. I am Kotlin Lover. Kotlin made me more productive in terms of coding. Do you want me to code for you ? Please don’t hesitate to contact me.