By default, eg. having Toolbar and some other Views in FrameLayout container causes Toolbar to appear on top of other views, no matter what their (views) order is.
Is it possible to force some of the views (eg. floating action buttons) to appear in front of Toolbar or should look for workaround?
edit:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fab="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/toolbar"/>
<!-- some RecyclerView goes here also -->
<com.github.clans.fab.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|right"
android:src="#drawable/ic_content_add"
fab:fab_colorNormal="#color/accentColor"
fab:fab_colorPressed="#color/accentColor"
android:layout_marginRight="20dp"
/>
</FrameLayout>
Result:
Problem: The oval button appears in front of RecyclerView, but behind Toolbar.
The floating action button has to have equal or higher elevation as the toolbar. Assuming your toolbar has elevation set to 8dp, the FAB needs to have the same at least.
Basically widgets with higher elevation move physically above and stop respecting the XML order.
Related
Per Google's Material Design guideline for Navigation drawer, to achieve Standard drawer for tablet or desktop devices, I would use NavigationView with SlidingPaneLayout for tablet devices instead of DrawerLayout for phone devices, which is to achieve Modal drawer.
I put a NavigationView as the first child view of SlidingPaneLayout. A problem occurred.
As you know SlidingPaneLayout's child views overlap if their combined width exceeds the available width in the SlidingPaneLayout. In this case, the child views expand to fill the available width in the SlidingPaneLayout. The user can slide the topmost view out of the way by dragging it back from the edge of the screen.
But my NavigationView's pane wouldn't slide. It just appears or disappears at maximum width without sliding animation.
How can I solve this?
<androidx.slidingpanelayout.widget.SlidingPaneLayout
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"
tools:context=".MainActivity">
<!-- The first child view becomes the left pane. When the combined
desired width (expressed using android:layout_width) would
not fit on-screen at once, the right pane is permitted to
overlap the left. -->
<com.google.android.material.navigation.NavigationView
android:id="#+id/navigationView"
android:layout_width="280dp"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/navigation_view_header"
app:menu="#menu/navigation_view" />
<!-- The second child becomes the right (content) pane. In this
example, android:layout_weight is used to expand this detail pane
to consume leftover available space when the
the entire window is wide enough to fit both the left and right pane.-->
<fragment
android:id="#+id/navigationHost"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="320dp"
android:layout_weight="1"
android:layout_height="match_parent"
app:navGraph="#navigation/main" />
</androidx.slidingpanelayout.widget.SlidingPaneLayout>
Add app:elevation="0dp" to the NavigationView.
<com.google.android.material.navigation.NavigationView
android:id="#+id/navigationView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
app:elevation="0dp"
app:headerLayout="#layout/navigation_view_header"
app:menu="#menu/navigation_view" />
If you inspect the layout, you can notice the NavigationView has elevation of 16dp by default. This causes the problem. It is probably that SlidingPaneLayout handles the two child views under the condition that they have the same elevations (0dp).
So a solution is to override NavigationView's default elevation (16dp) with 0dp.
Another solution is to wrap NavigationView with a FrameLayout or some ViewGroup.
<FrameLayout
android:layout_width="280dp"
android:layout_height="match_parent">
<com.google.android.material.navigation.NavigationView
android:id="#+id/navigationView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/navigation_view_header"
app:menu="#menu/navigation_view" />
</FrameLayout>
Then, you should specify layout_width with FrameLayout and NavigationView's layout_width to match_parent.
In spite of NavigationView's default elevation of 16dp, for its parent ViewGroup's elevation is 0dp, SlidingPaneLayout can properly handle.
After reading multiple Question/Answer in SO, I'm still searching for an answer.
My problem: in my application I use a Toolbar, but depending on the Fragment/Activity you're in the Toolbar menu item could change, for exemple on the first screen you will see only a Textview, in an other Fragment there will be the home arrow and an overflow menu sometimes there is two menu icons. The problem is that the title is centered with the space avaible wich is (toolbar space - menuitem space)
Here is my Toolbar xml:
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimaryDark"
app:contentInsetStart="0dp"
app:contentInsetLeft="0dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="#string/ciwy"
android:textSize="28sp"
android:textColor="#fff"/>
</RelativeLayout>
As you can see I tried contentInserStart but it doesn't change anything. I also used a relativelayout to center the textview. I need it to work atleast on API 19 (to try it on my phone).
Is there a solution to center the Textview in the middle of the bar even if I have menu items?
EDIT
Not finding any solution I just added an Image view in the RelativeLayout to act like the home button.
I'm trying to use the support library's BottomSheetDialogFragment to replicate the standard sheet that shows when you tap a Share button (see below). How would I achieve a similar layout, where there's a title at the top, independently scrollable content in the center, but an bottom anchored view with buttons that always stay on top.
You need to build a custom layout for the bottomSheet, for example share_bottom.xml. Within that layout you could
<LinearLayout 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="match_parent"
android:orientation="vertical"
app:layout_behavior="#string/bottom_sheet_behavior"
app:behavior_hideable="true"
app:behavior_peekHeight="200dp">
<TextView
android:layout_width="match_parent"
android:text="header"
android:layout_height="wrap_content"/>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"/>
<LinearLayout
android:layout_weight="0"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
And then include it at he bottom of your fragment's layout:
After that you can control the visibility of this sheet
//retrieve the bottomsheet
bottomSheet = (LinearLayout) findViewById(R.id.bottomSheet);
//get the behaviour controller
bsb = BottomSheetBehavior.from(bottomSheet);
//hide the sheet
bsb.setState(BottomSheetBehavior.STATE_HIDDEN);
//showthe sheet
bsb.setState(BottomSheetBehavior.STATE_EXPANDED);
I was also having the same problem. I solved using these steps.
Make FrameLayout as your root layout.
Include the view to be anchored as second child and first child should contain all the content of activity.
Animate the second child to be visible when bottom sheet is expanded and make it invisible when bottom sheet is collapsed.
The independently scrolling content inside bottom sheet can be acheived by using a scroll view or nested scroll view inside bottom sheet.
To dim background refer this link
This is just a workaround. Basically what I did is replicate the persistent bottom sheet to behave like modal sheet.
I am using Toolbar instead of actionabar in my appliaction.The toolbar works fine but the problem is that i want the app logo to appear in the center of the toolbar.The image will be in center if no menu items are displayed on the toolbar, but if i add search or refresh menu item to the toolbar the image also shifts.I want the toolbar to be in center always
Code
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar_home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/pink"
android:minHeight="56dp"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:contentInsetEnd="0dp"
app:contentInsetStart="0dp">
<RelativeLayout
android:id="#+id/rl_toolbar_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView
android:id="#+id/tv_home_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="#drawable/image"
android:drawablePadding="10dp"
/>
</RelativeLayout>
</android.support.v7.widget.Toolbar>
Using a bitmap drawable with center gravity as Toolbar background helps you create the required effect. e.g.,
Let's assume your image to be centered is centeree.png, and that will be wrapped inside drawable/toolbar_background.xml
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#android:drawable/centeree"
android:gravity="center" />
You can assign toolbar_background.xml as a background to toolbar in your layout
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#drawable/toolbar_background">
Also as an alternative, you can use a 9 patch drawable with a equal stretchable area on both sides.
You can not do it because of
One or more custom views. The application may add arbitrary child views to the Toolbar. They will appear at this position within the layout. If a child view's Toolbar.LayoutParams indicates a Gravity value of CENTER_HORIZONTAL the view will attempt to center within the available space remaining in the Toolbar after all other elements have been measured.
A easy way to do it, although its probably not the right way to do it.
I set my right side padding to the same width as my hamburger icon. Then everything else what I wanted in my dimens.xml. May need to be adjusted if you are adding action items on the right.
#dimen/app_bar_padding_right = 72dp
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:paddingTop="#dimen/app_bar_padding"
android:paddingBottom="#dimen/app_bar_padding"
android:paddingLeft="#dimen/app_bar_padding"
android:paddingRight="#dimen/app_bar_padding_right"
android:src="#drawable/nav_bar_logo"
android:contentDescription="#string/app_name" />
Add these attributes to the ImageView...
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
I am making a Layout where I need to position a Toolbar below a Map Fragment. Well it may hear easy but from my small knowledge I hit upon a tricky problem.
Well I hv achieved how to get the toolbar below the fragment body but I hit on some problems:
When using Linear Layout, I split both the components using weights which was perfect as i needed it but couldnt get the Toolbar to the bottom of the Fragment.
While using Relative Layout, I was able to bring the toolbar below the fragment but since the map is big, i couldnt adjust the height of the map and the toolbar goes out of bounds.
What i need is the combined effect of weights from the LinearLayout and the 'android:Layout_below' effect from the Relative Layout.
I will post my code here:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="#+id/app_bar"
layout="#layout/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/map1"
/>
<fragment
android:id="#+id/map1"
class="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="200dp"
/>
</RelativeLayout>
My toolbar is in a separate Layout 'app_bar'
The Toolbar is just like any View, and can be placed wherever you want. This is a big difference between it, and the ActionBar.
Just place the element wherever you would like inside your layout.
In your case, don't place the Toolbar relative to the fragment, but relative to the parent (RelativeLayout) then you can control it's placement/size independent of your fragment (which you can then place relative to your Toolbar if you want that control)
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="#+id/app_bar"
layout="#layout/app_bar"
android:layout_width="match_parent"
android:layout_height="80dp"// or whatever...
android:layout_alignParentBottom="true"
/>
<fragment
android:id="#+id/map1"
class="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_alignParentTop="true"
android:layout_above="#+id/app_bar"
android:layout_height="fill_parent"
/>