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 :
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 ?
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.