Search code examples
androidandroid-alertdialogandroid-coordinatorlayoutbottom-sheet

CoordinatorLayout adds extra space to BottomSheet in fullscreen Dialog


I'm working on an aplication targetting API 22.

I'm trying to add a BottomSheet at the bottom of a view, displayed in a fullscreen AlertDialog.

Unfortunately, CoordinatorLayout seems to add extra space at the bottom of the view.

However, this extra space is not added when this layout is set as contentView of an Activity

See the difference in these screenshots :

Difference between in-activity and in Dialog

I can't undestand why this layout is displayed correctly as an activity contentView, and not in a fullscreen Dialog.

You can find below the code producing these result, based on a newly created Android app from Android Studio wizard :

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/top_app_bar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:elevation="8dp"
            app:title="[Title]">
        </androidx.appcompat.widget.Toolbar>

    </com.google.android.material.appbar.AppBarLayout>

    <androidx.core.widget.NestedScrollView
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingBottom="0dp"
            android:orientation="vertical">

            <!-- [...] --> 

        </LinearLayout>
    </androidx.core.widget.NestedScrollView>

    <LinearLayout
        android:id="@+id/bottom_app_bar"
        android:layout_width="match_parent"
        android:layout_height="240dp"
        android:elevation="8dp"
        android:orientation="vertical"
        app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
        app:behavior_peekHeight="148dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="56dp"
            android:orientation="horizontal"
            android:padding="8dp">

            <TextView
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="2"
                android:text="BottomSheet Header" />

        </LinearLayout>

        <LinearLayout
            android:id="@+id/payment_buttons"
            android:layout_width="match_parent"
            android:layout_height="80dp"
            android:orientation="horizontal">

            <androidx.appcompat.widget.AppCompatButton
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:backgroundTint="@color/colorPrimary"
                android:text="TEST 1" />

            <androidx.appcompat.widget.AppCompatButton
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:backgroundTint="@color/colorPrimaryDark"
                android:text="TEST 2" />

            <androidx.appcompat.widget.AppCompatButton
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:backgroundTint="@color/colorAccent"
                android:text="TEST 3" />

            <androidx.appcompat.widget.AppCompatButton
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:backgroundTint="@android:color/holo_blue_bright"
                android:text="TEST 4" />

        </LinearLayout>
    </LinearLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

This is the MainActivity from which the AlertDialog is built and shown :

package com.axample.bottomsheetondialog

import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AlertDialog

import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

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

        bs_dialog.setOnClickListener {
            AlertDialog.Builder(this, R.style.AppTheme_FullscreenDialog)
                .setView(R.layout.view_with_bottomsheet)
                .create()
                .show()
        }
    }
}

And this is the simple-doing-nothing Activity where the problem do not occur

package fr.izypay.bottomsheetondialog

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

import kotlinx.android.synthetic.main.view_with_bottomsheet.*

class BottomsheetActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.view_with_bottomsheet)
        setSupportActionBar(top_app_bar)

        top_app_bar.title = "Bottomsheet in an activity"
    }

}

And finally, this is the Theme used for fullscreen-ness (see AppTheme.FullscreenDialog)

<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="AppTheme.FullscreenDialog" parent="AppTheme">

        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>

        <item name="android:windowFullscreen">false</item>
        <item name="android:windowIsFloating">false</item>
    </style>

</resources>

I really need this kind of layout to achieve a scrollable list (here with numbers) an an always-on-top growing toolbar at the bottom (the BottomSheet).

I know it can be achieved by some other way, but it sounds to me as a bug.

Does anyone know a solution for this to work ?


Solution

  • As pointed by Mike M. in this question's comments, I had to avoid using AlertDialog.Builder, and use Dialog instead, built by ourselves.

    In MainActivity, I had to replace

    AlertDialog.Builder(this, R.style.AppTheme_FullscreenDialog)
        .setView(R.layout.view_with_bottomsheet)
        .create()
        .show()
    

    by

    Dialog(this, R.style.AppTheme_FullscreenDialog).also {
        it.setContentView(R.layout.view_with_bottomsheet)
        it.show()
    }
    

    and the layout now behaves as expected.