How to prevent AppBarLayout going behind the status bar? - android

The AppBarLayout is going behind the status bar. I have made navigation bar translucent. If I use fitSystemWindow then the content doesn't show below the navigation bar. I want to retain content below navigation bar and make the AppBarLayout below status bar
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/fragment_main_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/fragment_main_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:title="#string/app_name"
app:layout_scrollFlags="scroll|enterAlways"
app:titleTextColor="#android:color/white"/>
<android.support.design.widget.TabLayout
android:id="#+id/fragment_main_tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
app:tabBackground="#android:color/white"
app:tabGravity="fill"
app:tabIndicatorColor="#color/colorPrimary"
app:tabMaxWidth="0dp"
app:tabSelectedTextColor="#color/colorPrimary"
app:tabTextColor="#color/tab_unselected">
</android.support.design.widget.TabLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/fragment_main_view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
</android.support.v4.view.ViewPager>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:layout_width="280dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#color/colorPrimary">
<ImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="bottom|right"
android:src="#drawable/navbar_bottom"/>
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>

You should set android:fitsSystemWindows="true" to your top-level layout (in this case DrawerLayout)

Try adding this to your CoordinatorLayout
android:fitsSystemWindows="true"
Formats: boolean
Boolean internal attribute to adjust view layout based on system
windows such as the status bar. If true, adjusts the padding of this
view to leave space for the system windows. Will only take effect if
this view is in a non-embedded activity.

Related

Android Viewpager behind virtual soft keys

I'm building a simple Android app with a viewpager. When I add a floating button in the main activity, he is well placed at the bottom-right of the screen.
But when I add this exact same button inside a fragment of a viewPager, the button goes BEHIND the virtual "soft keys" of my HTC One M8. Look at that (screenshoot with the two buttons):
screenshoot of the app with the floating buttons
So I've find the origin of the problem, but I don't know how to resolve it: the coordinator layout is OK (it stop before the soft keys) but the viewpager inside is not OK (it continues behind the soft keys). How to make it stop at the end of his container, the coordinator layout ? Why the Viewpager is doing that ?
screenshoot of the size of the coordinatorlayout
screenshoot of the size of the viewpager
I share with you the code of the mainActivity, containing the viewpager. I've used "match_parent" so I don't understand why it don't stop at the end of the parent:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
<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:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/myappbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:elevation="0dp">
<android.support.v7.widget.Toolbar
android:id="#+id/mytoolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/ThemeOverlay.AppCompat.Dark" />
<android.support.design.widget.TabLayout
android:id="#+id/mytabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabTextColor="#bcecda"
app:tabMode="fixed"
app:tabGravity="fill"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/add_depense_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_margin="16dp" />
</FrameLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="#menu/drawer_view"
app:headerLayout="#layout/nav_header" />
</android.support.v4.widget.DrawerLayout>

Move navigation drawer icon (hamburger)

I need to move navigation drawer icon (hamburger) from action bar to tab layout to make it look like provided for example. That should be performed on list scroll. Is there any possibility to move views from action bar to tab layout?
Action bar
Expected result
You can include a tabLayout in a toolbar like this:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
android:background="#color/colorPrimary"
android:layout_weight="1">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="top"
app:tabIndicatorColor="#color/colorAccent"
app:tabMaxWidth="0dp"
app:tabGravity="fill"
app:tabMode="scrollable"
android:background="#color/colorPrimary" />
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>

SetFitsSystemWindow programmatically doesn't work as expected

I'm trying to work with different AppBarLayouts in one Activity.
When a Fragment is loaded, it can call a "ToolbarManager", that handles the replacing of the currently active Toolbar (namely an AppBarLayout).
For some of these Toolbars (using CollapsingToolbarLayout) I want them to draw behind the StatusBar.
This works fine when setting the "fitsSystemWindow" to true in the XML.
But when using just a Toolbar with layout_scrollFlags="scroll", the Toolbar Title is displayed even behind the StatusBar.
To avoid this, I want to disable the "fitsSystemWindow" when loading such a Toolbar by using setFitsSystemWindow(false).
Disabling works fine, but when re-enabling by setFitsSystemWindow(true) for using with CollapsingToolbarLayout, the StatusBar is colored and the Toolbar is placed below the StatusBar with a padding in size of the StatusBar on top.
Image: Drawn below StatusBar instead of behind
When I don't use setFitsSystemWindow(true) and just set it to true in the XML layout, the display of CollapsingToolbarLayout is fine.
Is this a bug in setFitSystemWindow or is this method just different from the XML attribute?
Here are the layouts I use:
Activity:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/drawer_layout"
android:fitsSystemWindows="true"
tools:context=".activities.MainActivity"
style="#style/AppTheme">
<android.support.design.widget.CoordinatorLayout
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:fitsSystemWindows="true"
android:id="#+id/coordinator_layout">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:fitsSystemWindows="true"
android:layout_height="wrap_content">
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragment_container"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
</FrameLayout>
<ProgressBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
android:indeterminateDuration="1000"
android:layout_marginBottom="-7dp"
android:id="#+id/loadingBar"
style="#style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_gravity="center_horizontal|bottom"
android:gravity="bottom"/>
</android.support.design.widget.CoordinatorLayout>
<include layout="#layout/include_navigationview" />
The AppBarLayout is replaced every time a new Fragment is loaded.
The following layout is the Toolbar which should not draw behind the StatusBar, but the Toolbar should scroll (leaving only the TabLayout visible)
<android.support.design.widget.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:id="#+id/toolbar_discover"
android:fitsSystemWindows="true"
android:paddingBottom="0dp">
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:id="#+id/toolbar"
android:layout_height="?attr/actionBarSize"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:theme="#style/AppTheme.Toolbar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:layout_scrollFlags="scroll|snap">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="#+id/tablayout_discover"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:tabMode="fixed"
app:tabGravity="fill" />
</android.support.design.widget.AppBarLayout>
This used to work when I set fitsSystemWindows=false on the CoordinatorLayout in the MainActivity Layout. When doing so, the following CollapsingToolbar cannot draw behind the StatusBar.
<android.support.design.widget.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:id="#+id/toolbar_account"
android:fitsSystemWindows="true"
android:paddingBottom="0dp">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:contentScrim="?attr/colorPrimary"
android:fitsSystemWindows="true"
android:id="#+id/collapsingToolbarLayout">
<ImageView
android:layout_width="match_parent"
android:layout_height="250dp"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
app:layout_collapseMode="parallax"
android:id="#+id/banner_image"
android:src="#mipmap/img_header"/>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:id="#+id/toolbar"
android:fitsSystemWindows="false"
android:layout_height="?attr/actionBarSize"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:theme="#style/AppTheme.Toolbar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:layout_collapseMode="pin">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>

Coordinator Layout content is showing behind the status bar

I'm building a toolbar with a map fragment as part of it. The toolbar is fixed in position and is opaque.
Whenever the view's content is scrolled upwards, the map fragment moves with it but it is visible above the toolbar (and therefore between the status bar itself and the statusbar's orange background).
This is the resulting issue:
If I scroll a bit more, the scrim fades in normally, but too late.
Is there a way of not drawing the content when it goes above the toolbar? Or a way of making the status bar background to be drawn in front of the AppBarLayout content?
I've tried drawing a view in front of the AppBarLayout (right below the statusbar), but once the MapFragment is scrolled all the way up, it is then brought to front of that view, making the MapFragment visible during a small instant.
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="#dimen/promotion_details_image_height"
android:clickable="true"
android:fitsSystemWindows="true"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/orange"
android:fitsSystemWindows="true"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize">
<fragment
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_collapseMode="none"
tools:context=".restaurants.stores.StoresFragment" />
<ImageView
android:id="#+id/minimizeBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/stores_details_minimize_margin"
android:clickable="true"
android:contentDescription="#null"
android:paddingTop="#dimen/status_bar_height"
android:src="#drawable/selector_map_minimize_btn"
android:visibility="gone" />
<include
android:id="#+id/cardDetailsLayout"
layout="#layout/store_card_small_detail"
android:layout_width="match_parent"
android:layout_height="#dimen/stores_details_card_height"
android:layout_alignParentBottom="true"
android:layout_margin="10dp"
android:visibility="gone" />
</RelativeLayout>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light">
<com.app.views.FontTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:text="#string/store_toolbar_text"
android:textColor="#color/white"
android:textSize="#dimen/toolbar_text_size"
app:font="#string/fontFlamaMedium" />
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
Edit:
In the layout xml the android:layout_behavior attribute associated with my RecyclerView, but the toolbar's content has the correct behaviour, the problem is that it is visible under the statusbar, which I don't want it to.
You should remove your argument:android:fitsSystemWindows="true"
More about this on this blogPost from a google developper :
https://medium.com/google-developers/why-would-i-want-to-fitssystemwindows-4e26d9ce1eec
Remove this attribute from Toolbar
android:background="?attr/colorPrimary"
And add this attribute to CollapsingToolbar
app:contentScrim="?attr/colorPrimary"
The contentScrim will control the color of the Toolbar and ensure the color only appears when the background image has faded out

Rotation issue with CoordinatorLayout and DrawerLayout

I have set up a DrawerLayout and a CoordinatorLayout in order to use a modern layout with a NavigationView and collapsing toolbar.
It works just fine until the device is rotated. Then the main_content is moved to a new permanent location. If I remove the appbar_scrolling_view_behavior from the main_content FrameLayout rotation works, but the content is no longer aware of the Toolbar.
Any advice?
activity_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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00ff00">
<!-- ACTIONBAR START -->
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:background="#ff0000">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/colorPrimary"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:layout_scrollFlags="scroll|enterAlways"/>
</android.support.design.widget.AppBarLayout>
<!-- ACTIONBAR END -->
<!-- MAIN CONTENT START -->
<FrameLayout
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:background="#0000ff"/>
<!-- MAIN CONTENT END -->
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView ...>
<!-- NavigationView code omitted ... -->
</android.support.v4.widget.DrawerLayout>
fragment_main.xml (loaded into main_content)
<FrameLayout 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"
tools:context=".fragments.MainFragment">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Hello World!"/>
</FrameLayout>
A few points that should collectively resolve your problem:
The height of the AppBarLayout determins the expanded size of the collapsing toolbar, whilst the Toolbar determins the collapsed size. As such, you should set the AppBarLayout height to something more than the Toolbar (i.e. 280dp) to see the collapsing behaviour.
Immediately inside the AppBarLayout should be a CollapsingToolbarLayout, which contains the Toolbar and, optionally, other views too (normally an ImageView with a parallax collapse mode)
For the toolbar to collapse and expand correctly, it relies on a ViewGroup that supports nested scrolling (RecyclerView or NestedScrollView. As such, in your example you should try either changing main_content from a FrameLayout to a NestedScrollView, or conversely change the FrameLayout that forms the root layout of Fragment into a NestedScrollView.
Here is an example:
<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_height="match_parent"
android:layout_width="match_parent"
android:id="#+id/coordinator_layout">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="240dp"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" >
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/collapsing_toolbar_layout"
app:contentScrim="#color/primary"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/header_image"
android:src="#drawable/header_image"
android:scaleType="centerCrop"
android:contentDescription="#string/header_image"
app:layout_collapseMode="parallax"/>
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:id="#+id/toolbar"
app:layout_collapseMode="pin"
app:theme="#style/ThemeOverlay.AppCompat.Dark"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>

Categories

Resources