Let’s Create a Custom BottomSheetDialog without any library

Android Custom BottomSheetDialog Creation Tutorial using only android.app.Dialog class

In this example we want to see how to create our bottomsheetdialog without using any third party library or fancy API classes. The only class we use is the android.app.Dialog.

===

Demo

Here’s the gif demo of the project:

Video Tutorial

Here’s the video tutorial:

Gradle Scripts

(a) Build.gradle

Nothing special. No third party dependency.

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    testImplementation 'junit:junit:4.12'
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'

}

Layouts

Lets start by exploring the layouts in this project.

We have seven layouts:

1. activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    
    
    android_id="@+id/activity_main"
    android_layout_width="match_parent"
    android_layout_height="match_parent"
    android_orientation="vertical"
    android_background="#009688"
    tools_context=".MainActivity">

    <TextView
        android_id="@+id/headerTxt"
        android_layout_width="match_parent"
        android_layout_height="wrap_content"
        android_text="BottomDialog Tutorial"
        android_textAlignment="center"
        android_fontFamily="casual"
        android_textStyle="bold"
        android_textAppearance="@style/TextAppearance.AppCompat.Large"
        android_textColor="@color/white" />

    <LinearLayout
        android_layout_width="match_parent"
        android_layout_height="wrap_content"
        android_layout_marginLeft="16dp"
        android_layout_marginRight="16dp"
        android_orientation="horizontal"
        android_layout_marginTop="50dp">

    <Button
        android_id="@+id/btn_show_1"
        android_onClick="onClick"
        android_layout_width="0dp"
        android_layout_weight="1"
        android_layout_height="wrap_content"
        android_text="Show First"/>

    <Button
        android_id="@+id/btn_show_2"
        android_onClick="onClick"
        android_layout_width="0dp"
        android_layout_weight="1"
        android_layout_height="wrap_content"
        android_text="Show Second"/>

</LinearLayout>
</LinearLayout>
2. rectangular_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
              android_layout_width="match_parent"
              android_layout_height="wrap_content"
              android_background="@android:color/white"
              android_orientation="vertical">

    <TextView
        android_id="@+id/editMenuItem"
        android_onClick="onClick"
        android_layout_width="match_parent"
        android_layout_height="wrap_content"
        android_background="?android:attr/selectableItemBackground"
        android_clickable="true"
        android_drawableLeft="@drawable/ic_edit"
        android_drawablePadding="16dp"
        android_gravity="center_vertical"
        android_padding="16dp"
        android_text="Edit"
        android_textColor="#666666"
        android_textSize="14sp"/>

    <TextView
        android_id="@+id/starMenuItem"
        android_onClick="onClick"
        android_layout_width="match_parent"
        android_layout_height="wrap_content"
        android_background="?android:attr/selectableItemBackground"
        android_clickable="true"
        android_drawableLeft="@drawable/ic_star"
        android_drawablePadding="16dp"
        android_gravity="center_vertical"
        android_padding="16dp"
        android_text="Star"
        android_textColor="#666666"
        android_textSize="14sp"/>

    <TextView
        android_layout_width="match_parent"
        android_layout_height="wrap_content"
        android_background="?android:attr/selectableItemBackground"
        android_clickable="true"
        android_drawableLeft="@drawable/ic_circle"
        android_drawablePadding="16dp"
        android_gravity="center_vertical"
        android_padding="16dp"
        android_text="Set"
        android_textColor="#666666"
        android_textSize="14sp"/>

    <TextView
        android_layout_width="match_parent"
        android_layout_height="wrap_content"
        android_background="?android:attr/selectableItemBackground"
        android_clickable="true"
        android_drawableLeft="@drawable/ic_send"
        android_drawablePadding="16dp"
        android_gravity="center_vertical"
        android_padding="16dp"
        android_text="Send"
        android_textColor="#666666"
        android_textSize="14sp"/>

    <TextView
        android_layout_width="match_parent"
        android_layout_height="wrap_content"
        android_background="?android:attr/selectableItemBackground"
        android_clickable="true"
        android_drawableLeft="@drawable/ic_alert"
        android_drawablePadding="16dp"
        android_gravity="center_vertical"
        android_padding="16dp"
        android_text="Alert"
        android_textColor="#666666"
        android_textSize="14sp"/>

    <TextView
        android_layout_width="match_parent"
        android_layout_height="wrap_content"
        android_background="?android:attr/selectableItemBackground"
        android_clickable="true"
        android_drawableLeft="@drawable/ic_delete"
        android_drawablePadding="16dp"
        android_gravity="center_vertical"
        android_padding="16dp"
        android_text="Delete"
        android_textColor="#666666"
        android_textSize="14sp"/>
</LinearLayout>
3. curved_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
              android_layout_width="match_parent"
              android_layout_height="wrap_content"
              android_background="@drawable/shape_dialog"
              android_orientation="vertical">

    <TextView
        android_layout_width="match_parent"
        android_layout_height="wrap_content"
        android_background="?android:attr/selectableItemBackground"
        android_clickable="true"
        android_drawableLeft="@drawable/ic_edit"
        android_drawablePadding="16dp"
        android_gravity="center_vertical"
        android_padding="16dp"
        android_text="Edit"
        android_textColor="#666666"
        android_textSize="14sp"/>

    <TextView
        android_layout_width="match_parent"
        android_layout_height="wrap_content"
        android_background="?android:attr/selectableItemBackground"
        android_clickable="true"
        android_drawableLeft="@drawable/ic_star"
        android_drawablePadding="16dp"
        android_gravity="center_vertical"
        android_padding="16dp"
        android_text="Star"
        android_textColor="#666666"
        android_textSize="14sp"/>

    <TextView
        android_layout_width="match_parent"
        android_layout_height="wrap_content"
        android_background="?android:attr/selectableItemBackground"
        android_clickable="true"
        android_drawableLeft="@drawable/ic_circle"
        android_drawablePadding="16dp"
        android_gravity="center_vertical"
        android_padding="16dp"
        android_text="Set"
        android_textColor="#666666"
        android_textSize="14sp"/>

    <TextView
        android_layout_width="match_parent"
        android_layout_height="wrap_content"
        android_background="?android:attr/selectableItemBackground"
        android_clickable="true"
        android_drawableLeft="@drawable/ic_send"
        android_drawablePadding="16dp"
        android_gravity="center_vertical"
        android_padding="16dp"
        android_text="Send"
        android_textColor="#666666"
        android_textSize="14sp"/>

    <TextView
        android_layout_width="match_parent"
        android_layout_height="wrap_content"
        android_background="?android:attr/selectableItemBackground"
        android_clickable="true"
        android_drawableLeft="@drawable/ic_alert"
        android_drawablePadding="16dp"
        android_gravity="center_vertical"
        android_padding="16dp"
        android_text="Alert"
        android_textColor="#666666"
        android_textSize="14sp"/>

    <TextView
        android_layout_width="match_parent"
        android_layout_height="wrap_content"
        android_background="?android:attr/selectableItemBackground"
        android_clickable="true"
        android_drawableLeft="@drawable/ic_delete"
        android_drawablePadding="16dp"
        android_gravity="center_vertical"
        android_padding="16dp"
        android_text="Delete"
        android_textColor="#666666"
        android_textSize="14sp"/>
</LinearLayout>

Animations

1. translate_dialog_in.xml
<?xml version="1.0" encoding="utf-8"?>
<translate 
           android_duration="300"
           android_fromXDelta="0"
           android_fromYDelta="100%"
           android_toXDelta="0"
           android_toYDelta="0">
</translate>
2. translate_dialog_out.xml
<?xml version="1.0" encoding="utf-8"?>
<translate 
           android_duration="300"
           android_fromXDelta="0"
           android_fromYDelta="0"
           android_toXDelta="0"
           android_toYDelta="100%">
</translate>

Styles

(a). styles.xml
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <style name="BottomDialog" parent="@style/Base.V7.Theme.AppCompat.Light.Dialog">
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
    </style>

    <style name="BottomDialog.Animation" parent="Animation.AppCompat.Dialog">
        <item name="android:windowEnterAnimation">@anim/translate_dialog_in</item>
        <item name="android:windowExitAnimation">@anim/translate_dialog_out</item>
    </style>
</resources>

Java Code.

We have the following java classes for this project:

  1. MainActivity.java
MainActivity.java

Our main activity class.

package info.camposha.mrsbottomdialog;

import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    /**
     * I'll start by creating two utility methods.
     * @param message
     */
    private void show(String message){
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
    }
    public static int dp2px(Context context, float dpVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal,
                context.getResources().getDisplayMetrics());
    }
    /**
     * Here am just creating a bottomsheet dialog from the android.app.Dialog
     * class
     */
    private void showFirstBottomDialog() {
        Dialog bottomDialog = new Dialog(this, R.style.BottomDialog);
        View contentView = LayoutInflater.from(this).inflate(R.layout.rectangular_dialog, null);
        bottomDialog.setContentView(contentView);
        ViewGroup.LayoutParams layoutParams = contentView.getLayoutParams();
        layoutParams.width = getResources().getDisplayMetrics().widthPixels;
        contentView.setLayoutParams(layoutParams);
        bottomDialog.getWindow().setGravity(Gravity.BOTTOM);
        bottomDialog.setCanceledOnTouchOutside(true);
        bottomDialog.getWindow().setWindowAnimations(R.style.BottomDialog_Animation);
        bottomDialog.show();
    }

    /**
     * Then here is the second, a little bit curved dialog
     */
    private void showSecondBottomDialog() {
        Dialog bottomDialog = new Dialog(this, R.style.BottomDialog);
        View contentView = LayoutInflater.from(this).inflate(R.layout.curved_dialog, null);
        bottomDialog.setContentView(contentView);
        ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) contentView.getLayoutParams();
        params.width = getResources().getDisplayMetrics().widthPixels - dp2px(this, 16f);
        params.bottomMargin = dp2px(this, 8f);
        contentView.setLayoutParams(params);
        bottomDialog.setCanceledOnTouchOutside(true);
        bottomDialog.getWindow().setGravity(Gravity.BOTTOM);
        bottomDialog.getWindow().setWindowAnimations(R.style.BottomDialog_Animation);
        bottomDialog.show();
    }
    /**
     * Let's handle a few item clicks. For buttons and just two of our
     * menu items. You can add more case statements to handle more
     * menu items.
     * @param view
     */
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn_show_1:
                showFirstBottomDialog();
                break;
            case R.id.btn_show_2:
                showSecondBottomDialog();
                break;
            case R.id.editMenuItem:
                show("Edit Clicked");
                break;
            case R.id.starMenuItem:
                show("Star Clicked");
                break;
        }
    }

    /**
     * Our onCreate callback
     * @param savedInstanceState
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

}
//end
Download

You can download the full source code below or watch the video from the link provided.

No. Location Link
1. GitHub Direct Download
2. GitHub Browse
3. YouTube Video Tutorial
4. YouTube ProgrammingWizards TV Channel
Share



Share an Example

Share an Example

Browse
What is the capital of Egypt? ( Cairo )