CoordinatorLayout adds extra space to BottomSheet in fullscreen Dialog - android

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.

Related

Android How to center title of top actionBar?

To start my objective is to center my title. I have started a project by selecting the bottom navigation activity template. This came with 3 fragments and a main activity. I am attempting to center the title of the top action bar. I have attempted to access the mobile_navigation by id and align the text within the MainActivity but this does not seem to work. I also tried adding a textAlignment attribute in the homeFragment.xml but this did not work either. I do not find any similar scenarios anyone know how could I be able to resolve this?
mobile_navigation.xml:
<?xml version="1.0" encoding="utf-8"?>
<navigation 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/mobile_navigation"
app:startDestination="#+id/navigation_home">
<fragment
android:id="#+id/navigation_home"
android:name="com.Example.exmaple.ui.home.HomeFragment"
android:label="#string/app_name"
tools:layout="#layout/fragment_home" />
<fragment
android:id="#+id/navigation_dashboard"
android:name="com.Example.exmaple.ui.dashboard.DashboardFragment"
android:label="#string/title_dashboard"
tools:layout="#layout/fragment_dashboard" />
<fragment
android:id="#+id/navigation_notifications"
android:name="com.Example.exmaple.ui.notifications.NotificationsFragment"
android:label="#string/title_notifications"
tools:layout="#layout/fragment_notifications" />
</navigation>
I also attempted to add:
android:gravity="center"
Any feedback welcomed.
To use a custom title in your Toolbar all you need to do is remember is that Toolbar is just a fancy ViewGroup so you can add a custom title like so:
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar_top"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
android:background="#color/action_bar_bkgnd"
app:theme="#style/ToolBarTheme" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Toolbar Title"
android:layout_gravity="center"
android:id="#+id/toolbar_title" />
</android.support.v7.widget.Toolbar>
This means that you can style the TextView however you would like because it's just a regular TextView. So in your activity you can access the title like so:
Toolbar toolbarTop = (Toolbar) findViewById(R.id.toolbar_top);
TextView mTitle = (TextView) toolbarTop.findViewById(R.id.toolbar_title);
setSupportActionBar(toolbar);
mTitle.setText(toolbar.getTitle());
getSupportActionBar().setDisplayShowTitleEnabled(false);
Try below code may works for you
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
getSupportActionBar().setCustomView(R.layout.abs_layout);
Better add a layout file for tool bar and center the title there and add dynamically on create or include in your fragment layout file.
I was able to figure out the solution. I will post it incase anyone runs across this issue.
I added the following to the Main Activity xml:
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolBar"
android:elevation="5dp"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorBlack">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/colorTransparent"
android:layout_alignParentStart="true"
android:layout_gravity="start"
android:text="#string/log_out"
android:textAlignment="center"
android:textColor="#color/lightblue"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/app_name"
android:textColor="#color/colorApp"
android:textSize="20sp"/>
<ImageButton
android:layout_width="20dp"
android:layout_height="20dp"
android:src="#drawable/ic_add"
android:tint="#color/lightblue"
android:layout_alignParentEnd="true"
android:layout_gravity="end"
android:background="#color/colorBlack" />
</androidx.appcompat.widget.Toolbar>
I also took away the padding top from the androidx.constraintlayout.widget.ConstraintLayout opening tag in the Main Activity XML
Added the following style to styles.xml:
<style name="AppTheme.NoActionBar" parent="AppTheme">
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
</style>
Finally in the Android manifest I added the following theme to the Main Acivity:
android:theme="#style/AppTheme.NoActionBar"

Is it possible to embed the floating action button into the action bar?

I want to get something like this. Is it possible?
The answer to this question is not applicable without an actual header item, which I don't have here. Action bar is not an item I can anchor to, or at least I don't know a way to do that.
This can be done using a custom toolbar as supportActionBar.
And instead of using layout_anchor to place the FAB, we can constraint it to the tool bar using ConstraintLayout as a root view.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
</com.google.android.material.appbar.AppBarLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="64dp"
android:layout_marginRight="64dp"
android:src="#drawable/ic_baseline_play_arrow_24"
app:layout_constraintBottom_toBottomOf="#id/appbar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/appbar" />
</androidx.constraintlayout.widget.ConstraintLayout>
And make sure to use AppTheme with NoActionBar like Theme.MaterialComponents.DayNight.NoActionBar
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
Then set supportActionBar in activity:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
}
Preview:
I have tried a solution but it isn't direct one and hope it will help
in the root coordinate layout create a child empty layout at the top of it and change the background color to be the same color of action bar , then new empty layout will be after action bar directly and it will be shown as part of the action bar and give it proper height as you want .and your code will be like that
Empty layout:
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:id="#+id/tst"
android:background="#android:color/black"
android:layout_height="50dp"/>
you can increase the height as you want but it is the best height for my device
Floating Actio Button:
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_anchor="#id/tst"
app:layout_anchorGravity="top|center"
/>

Transparent bottom sheet layout in Android

I am trying to make a transparent bottom sheet layout, that would allow me to see the contents of the view below it. The bottom sheet is working as expected, however when I set the background to either #null or #android:color/transparent, the layout's view is white, as opposed to transparent. My layout is as follows:
app_bar_main.xml:
<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:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/coordinatorLayout"
android:background="#android:color/transparent"
android:fitsSystemWindows="true"
tools:context=".core.activities.MainActivity">
<!-- stuff here -->
<LinearLayout
android:id="#+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:background="#null"
android:orientation="vertical"
app:layout_behavior="#string/bottom_sheet_behavior">
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
The linear layout with id bottom_sheet holds, well, my bottom sheet. The sheet itself is defined as follows:
<?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"
android:layout_width="match_parent"
android:background="#null"
android:layout_height="match_parent">
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#null"
android:orientation="vertical">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/bottom_sheet_placeholder_layout"
android:layout_weight="0.6"
android:layout_width="match_parent"
android:background="#null"
android:layout_height="50dp"
android:orientation="horizontal">
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/bottom_sheet_layout"
android:layout_margin="0dp"
android:layout_weight="0.4"
android:layout_width="match_parent"
android:background="#color/my_background"
android:layout_height="wrap_content"
android:orientation="vertical">
<ProgressBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:id="#+id/my_progress_bar" />
<TextView
android:layout_marginTop="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:textColor="#color/my_text"
android:id="#+id/txt_my_info"
android:layout_gravity="center_horizontal"
android:visibility="gone"
android:textSize="48px" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/txt_my_address"
android:textColor="#color/my_secondary_text"
android:visibility="gone"
android:layout_gravity="center_horizontal" />
</LinearLayout>
</LinearLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/btn_edit_tree_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:layout_marginTop="-62dp"
android:elevation="100dp"
android:src="#drawable/ic_create_black_24dp"
app:layout_anchor="#id/bottom_sheet_layout"
app:layout_anchorGravity="top|end|right"
app:useCompatPadding="true"/>
</android.support.design.widget.CoordinatorLayout>
The answer is much more easier: just add this line
myDialog
.getWindow()
.findViewById(R.id.design_bottom_sheet)
.setBackgroundResource(android.R.color.transparent);
And don't change standard ids (R.id.design_bottom_sheet and android.R.color.transparent). It makes background of Bottom Sheet Dialog transparent
private void setupDialogBackground() {
getDialog().setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface dialog) {
BottomSheetDialog d = (BottomSheetDialog) dialog;
FrameLayout bottomSheet = (FrameLayout) d.findViewById(R.id.design_bottom_sheet);
if (bottomSheet == null)
return;
bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
bottomSheet.setBackground(null);
}
});
}
add this in styles.xml
<style name="TransparentDialog" parent="Theme.Design.Light.BottomSheetDialog">
<item name="android:windowCloseOnTouchOutside">false</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:colorBackground"> #android:color/transparent</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:backgroundDimAmount">0.3</item>
<item name="android:windowFrame">#null</item>
<item name="android:windowIsFloating">true</item>
</style>
BottomSheetDialog bsDialog = new BottomSheetDialog(this,R.style.TransparentDialog);
bsDialog.setContentView(R.layout.bottomsheet_dialog);
bsDialog.show();
and voila it works
I had to wait until after setContentView was called in onActivityCreated in order to access the container. Also while getDialog().getWindow().findViewById(R.id.design_bottom_sheet) did successfully find the FrameLayout, I decided to avoid explicitly calling out the internally defined id by using getView().getParent().
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState); // setContentView called here
((View) getView().getParent()).setBackgroundColor(Color.TRANSPARENT);
}
Add this in your bottomSheet setupDialog(final Dialog dialog, int style)
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
and also add android:background="#android:color/transparent" to root view
Just need to use this style:
<style name="BaseBottomSheetDialogThem" parent="#style/Theme.Design.Light.BottomSheetDialog">
<item name="android:windowIsFloating">true</item>
<item name="android:backgroundDimEnabled">false</item>
</style>
and set your style to BaseBottomSheetDialogThem.
Here is the kotlin version thanks to kolorszczak . Hope it save someones time converting .
val dialog = BottomSheetDialog(activity!!)
dialog.setOnShowListener {
var dialogTmp: BottomSheetDialog = it as BottomSheetDialog
var bottomSheet: FrameLayout? =
dialogTmp.findViewById(R.id.design_bottom_sheet) as FrameLayout?
?: return#setOnShowListener
bottomSheet?.background = null
}
Create in your color.xml : <color name="colorTransparent">#00000000</color>
and use android:background="#color/colorTransparent"
change color background
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/bottom_sheet_placeholder_layout"
android:layout_weight="0.6"
android:layout_width="match_parent"
android:background="#00FFFFFF"
android:layout_height="50dp"
android:orientation="horizontal">
</LinearLayout>
Try it!!

Android: Activity showing extra space at bottom when padding 0dp - Related to json?

I have an activity that shows extra space at the bottom even though I have no bottom padding applied. Style code, xml code, java code and a screenshot are below and the relevant json data is here:
http://lara.rufflecol.es/strollcharlton/strollcharlton_data_1_2.json
It isn't a huge issue it is just annoying! Have already tried to using android:fillViewport set as true or false but it doesn't seem to make any difference. Is the problem related to my json?
UsefulLinks.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:background="#color/dark_green"
android:minHeight="?attr/actionBarSize" />
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/toolbar"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/useful_links"
style="#style/UsefulLinksTextStyling"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="left" />
</LinearLayout>
</ScrollView>
</LinearLayout>
styles.xml
<style name="UsefulLinksTextStyling" parent="#android:style/TextAppearance.Medium">
<item name="android:textColor">#color/white</item>
<item name="android:textSize">#dimen/fifteen_size</item>
<item name="android:paddingTop">15dp</item>
<item name="android:paddingLeft">15dp</item>
<item name="android:paddingRight">15dp</item>
</style>
UsefulLinks.java
TextView usefulLinksIntroTextView = (TextView) findViewById(R.id.useful_links);
usefulLinksIntroTextView.setText(Html.fromHtml(data.getUsefulLinks()));
usefulLinksIntroTextView.setMovementMethod(LinkMovementMethod.getInstance());
Screenshot
ensure the html that you are setting to the textview does not having blank space inside of it
change your base LinearLayout to wrap_content so that if the html takes up less than the screen height you don't have "extra padding"
You can also turn on "show layout bounds" for your application, that way you will understand which View is giving you the "extra padding" http://tysmith.me/post/27035355999/layoutbounds combine it with the Hierarchy Viewer http://developer.android.com/tools/performance/hierarchy-viewer/index.html to work out which View is at fault

How can I add divider between action Items in Toolbar

I want to design a toolbar like:.
I have done most of it but having some problem.
I don't know how to make a divider between the toolbars items and also having no idea how to set a counter variable attached to the action button that increment as order takes place like given in the picture.
Any suggestions?
You can place your layout like below:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/..."
android:showAsAction="always."
android:icon="#drawable/..."
android:title="#string/..."
android:actionLayout="#layout/your_layout_here"/>
or
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/..."
android:showAsAction="always."
android:icon="#drawable/..."
android:title="#string/..."
android:actionViewClass="your_class"/>
where "your_class" - class which inflate and implement your view with separator
Try to create a custom toolbar. Add your views between the toolbar's opening and closing tags.
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="56dip"
android:background="#ff0000">
<!-- the back button -->
<ImageView
android:id="#+id/backButton"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="left"
android:clickable="true"
android:onClick="onBackButtonClick"
android:paddingLeft="16dip"
android:paddingRight="16dip"
android:src="#drawable/ic_back" />
...
<!-- the devider -->
<View
android:layout_width="1dip"
android:layout_height="match_parent"
android:background="#ffffff" />
<ImageView .../>
</android.support.v7.widget.Toolbar>

Categories

Resources