I'm building an app and when I load the view with the BottomNavigationView, I have odd issues all the time, sometimes, I have an extra space and other times, the toolbar is wrongly located, for example:
With bottom navigation:
Without bottom navigation:
This is my code for the 1st image:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#android:color/white"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
layout="#menu/toolbar_recipe" />
<FrameLayout
android:id="#+id/content_frame"
android:layout_height="0dp"
android:layout_weight="1"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_width="match_parent" />
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:menu="#menu/bottom_nav_menu"
app:labelVisibilityMode="unlabeled"
app:itemBackground="#color/colorPrimary"
app:itemIconTint="#color/bottom_nav_color"
app:itemTextColor="#color/bottom_nav_color" />
</LinearLayout>
</RelativeLayout>
Toolbar:
<?xml version="1.0" encoding="UTF-8" ?>
<android.support.v7.widget.Toolbar
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/toolbar_recipe"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:theme="#style/ToolBarStyle"
android:minHeight="?android:attr/actionBarSize"
android:background="#color/colorPrimary"/>
And this is how it behaves with the CoordinatorLayout, after I set the paddingTop as ?attr/actionBarSize the FrameLayout moved some space, but it's still wrongly located.
With CoordinatorLayout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#android:color/white"
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:fitsSystemWindows="true"
android:layout_above="#+id/bottom_navigation">
<include
layout="#menu/toolbar_recipe" />
<FrameLayout
android:id="#+id/content_frame"
android:paddingTop="?attr/actionBarSize"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:menu="#menu/bottom_nav_menu"
app:labelVisibilityMode="unlabeled"
app:itemBackground="#color/colorPrimary"
app:itemIconTint="#color/bottom_nav_color"
app:itemTextColor="#color/bottom_nav_color" />
</RelativeLayout>
Without that addition, it just stays behind. I'm working in Android 8+, but I don't think it's the issue and I'm out of ideas how to coordinate that situation. Has anyone experienced it?
Thanks for any comment, especially of why it's happening since I cannot understand it.
I found the answer based on this line:
android:fitsSystemWindows="true"
I needed to add it to the root element more or less like this:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#android:color/white"
android:layout_width="match_parent"
android:fitsSystemWindows="true"
android:layout_height="match_parent">
And here is a description of the property:
System windows are the parts of the screen where the system is drawing
either non-interactive (in the case of the status bar) or interactive
(in the case of the navigation bar) content.
Most of the time, your app won’t need to draw under the status bar or
the navigation bar, but if you do: you need to make sure interactive
elements (like buttons) aren’t hidden underneath them. That’s what the
default behavior of the android:fitsSystemWindows="true" attribute
gives you: it sets the padding of the View to ensure the contents
don’t overlay the system windows.
I found it here:
Why would I want to fitsSystemWindows?
Related
I am building an app with a BottomNavigationView where the first tab is loaded correctly:
Tab 1:
However, when I switch to the next tab, it seems the Framelayout goes under the Toolbar like this:
Tab 2:
Tab 1 again:
This is my Layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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">
<FrameLayout
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/bottom_navigation"/>
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:menu="#menu/bottom_nav_menu"
app:labelVisibilityMode="unlabeled"
app:itemBackground="#color/colorPrimary"
app:itemIconTint="#color/bottom_nav_color"
app:itemTextColor="#color/bottom_nav_color" />
</RelativeLayout>
There are similar cases like this one:
Part of Fragment items hides under Action bar
But their solutions don't work in my case. Any idea what should I change? Or why the Toolbar loses priority? I already tested to create one by myself in the Layout and it didn't work properly too.
P.S.
I'm loading some WebViews, but I doubt it influences.
Your code is working fine for me. Although you can set margin top for frame layout
android:layout_marginTop="?attr/actionBarSize"
I found how to fix it using a CoordinatorLayout:
<?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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
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:fitsSystemWindows="true"
android:layout_above="#+id/bottom_navigation">
<FrameLayout
android:id="#+id/content_frame"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:menu="#menu/bottom_nav_menu"
app:labelVisibilityMode="unlabeled"
app:itemBackground="#color/colorPrimary"
app:itemIconTint="#color/bottom_nav_color"
app:itemTextColor="#color/bottom_nav_color" />
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>
I got an idea from here:
https://forums.xamarin.com/discussion/146285/how-to-do-appbarlayout-with-collapsing-toolbarlayout-that-will-collapse-when-viewpager-scroll
I want to hide my bottom bar on scroll but a FAB should stay on the screen.
If I put the FAB on top of BottomNavigationView using anchors but it appears behind it.
If I put layout_insetEdge="bottom" to the BottomNavigationView then it works but make my tests fail (https://issuetracker.google.com/issues/70162122) so I cannot use that at the moment.
Layout:
<?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/mainLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".screens.main.MainActivity">
<FrameLayout
android:id="#+id/mainContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/scrolling_view_behaviour" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/mainNewQuestionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/spacing_8dp"
app:layout_anchor="#+id/mainBottomNavigationView"
app:layout_anchorGravity="top|right|end"
app:srcCompat="#drawable/create_question"
tools:visibility="visible" />
<android.support.design.widget.BottomNavigationView
android:id="#+id/mainBottomNavigationView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:itemBackground="#color/my_gray"
app:itemIconTint="#drawable/selector_bottombar_item"
app:itemTextColor="#drawable/selector_bottombar_item"
app:layout_anchor="#id/mainContainer"
app:layout_anchorGravity="bottom"
app:layout_behavior="#string/hide_bottom_navigation_view_behaviour"
app:menu="#menu/bottom_navigation_main" />
</android.support.design.widget.CoordinatorLayout>
Just use:
<androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_gravity="bottom"
.../>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_gravity="top"
app:layout_anchor="#id/bottom_navigation"
app:layout_anchorGravity="top|end"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
You seem to be having a Z-Ordering issue here.
You could try the fab.bringToFront() followed by fab.invalidate() for api's below 21, and ViewCompat.setZ(fab, someFloat) for api's above 21.
I used these methods to bring a custom FloatingActionMenu, consisting of a series of FAB's I wrote for a project, to the front so they would overlap everything on the screen.
I'm trying to place two Fragments next to each other, but I can't get rid of a space between the ActionBar and my application contents :
Here is my XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="horizontal" android:layout_width="match_parent"
android:fitsSystemWindows="true"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:elevation="0dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.tce.manager.MainActivity"
tools:showIn="#layout/app_bar_main">
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:elevation="2dp"
android:name="com.tce.manager.DeviceListFragment"
android:layout_weight="3"
android:id="#+id/fragment_device_list" />
<FrameLayout
android:background="#android:color/darker_gray"
android:elevation="0dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2" />
</LinearLayout>
I already tried to change margins and padding for the Toolbar and AppBarLayout
Remove android:fitsSystemWindows="true"
If it's set to true, then it adjusts the padding of this view to leave space for the system windows.
Try removing the top padding between the action bar and fragment. Android Studio sometimes adds the top padding. Also, change the constraints so that Fragment renders properly
Hello I'm attempting to simply put my content below the toolbar but at the moment when I run my application some of the content is hidden behind it when it should be below it.
I have read up about using a frame layout to attempt to separate it but I have come a little stuck. I'm currently using a basic android studio navigation drawer template provided with the software and was wondering what changes I have to make.
My coordinator layout
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.design.widget.CoordinatorLayout>
My drawer layout
<android.support.v4.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<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:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
What changes do I need to make?
Many ViewGroups allow their children to overlap. These include FrameLayout, RelativeLayout, CoordinatorLayout, and DrawerLayout. One that does not allow its children to overlap is LinearLayout.
The answer to your question really depends on what the end result should be. If you are trying to just have a Toolbar that is always on screen and some content below it, then you don't need a CoordinatorLayout and AppBarLayout at all, you can just use a vertical LinearLayout with two children:
<LinearLayout android:orientation="vertical" ...>
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
... />
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
... />
</LinearLayout>
Note layout attributes of the FrameLayout.
If you want to do the fancy stuff where the toolbar scrolls on and off the screen as you scroll the content, then you need an AppBarLayout and you need to give your content area a special attribute like this:
<android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
... >
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll"
... />
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
... />
</android.support.design.widget.CoordinatorLayout>
app:layout_behavior="#string/appbar_scrolling_view_behavior"
Add this code to your frame tag
As #Brian Hoang and #Karakuri said using the layout_behaviour property:
app:layout_behavior="#string/appbar_scrolling_view_behavior"
seems to be a very good solution. Even if you don't have any animations at the moment but you plan to have in the future then you can still keep the CoordinatorLayout and an AppBarLayout in case you want to add animations in the future.
What the property seems to do in general from my understanding, is to calculate the height of the whole AppBarLayout UI component. The UI component that uses the layout_behaviour property with the #string/appbar_scrolling_view_behaviour will automatically be shown exactly below the AppBarLayout regardless of what the height is.
In this way there is no need to hardcode any top margins in the UI that is supposed to be under the AppBarLayout.
In the code below the include_app_bar_with_tabs_layout (AppBarLayout) has a fixed height of 200dp (it can be wrap_content or anything else). Then the RelativeLayout that contains the content of the screen uses the layout_behaviour property.
Have a look at the code and UI image below:
<?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:fitsSystemWindows="true">
<include
layout="#layout/include_app_bar_with_tabs_layout"
android:layout_width="match_parent"
<!-- this can be anything, even wrap_content -->
android:layout_height="200dp" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/Green"
<!-- this tells it to be below the include_app_bar_with_tabs_layout (AppBarLayout) -->
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<android.support.v4.view.ViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/adView" />
<com.google.android.gms.ads.AdView
android:id="#id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
app:adSize="BANNER"
app:adUnitId="#string/banner_ad_unit_id"
tools:background="#color/green"
tools:layout_height="50dp" />
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
EDIT: See Using the Master/Detail template in ViewPager Fragments (download link) for full code
I have a toolbar and a recyclerView. When the layout is first inflated the last item of the recyclerView is out of the scroll-able region of the screen and is therefore not visible. After rotating the item appears. It is apparent that the toolbar is pushing the recyclerView outside the boundaries of the screen. If I add padding to the bottom of the recyclerView with the height of the toolbar the issue is resolved BUT only for the initial inflation of the layout. After rotation I am left with a gap on the bottom of the screen. I'm using sdk 23.
A possible workaround would be to programmatically remove the padding after the very first inflation of the layout. I assume I could use:
onCreateView(){ if (onSaveInstanceState != null) removePadding();}
However, I'd rather not have to do a dodgy work-around.
My app is basically exactly the same as the Master/Detail-flow template supplied in Android Studio, except that I use fragments and a single Activity. There is no such issue in the template.
Any ideas?
fragment_item_list.xml
<?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:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<include layout="#layout/item_list" />
</FrameLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
android:src="#android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
item_list.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView 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/item_list"
android:name="com.idragonit.scrolltabs.ItemListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
app:layoutManager="LinearLayoutManager"
tools:context="com.idragonit.scrolltabs.ItemListActivity"
tools:listitem="#layout/item_list_content" />
item_list_content.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/text_margin"
android:textAppearance="?attr/textAppearanceListItem" />
<TextView
android:id="#+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/text_margin"
android:textAppearance="?attr/textAppearanceListItem" />
</LinearLayout>
snippet of ItemListFragment.java
Toolbar toolbar = (Toolbar) root.findViewById(R.id.toolbar);
toolbar.setTitle("List");
I added:
android:layout_gravity="fill_vertical"
android:layout_marginBottom="?attr/actionBarSize"
to item_list.xml. The issue persists. The first time the layout is inflated it shows the bottom element as expected. After rotating to landscape and back to portrait it leaves a margin the size of the actionBar at the bottom of the screen.
This issue does not happen in the Master/Detail-flow template available in Android Studio and the code for item_list.xml, item_list_twopane.xml and activity_item_list are exactly the same as the code used in item_list.xml, land/item_list.xml and fragment_item_list.xml in my project. Yet, as the attached images show, the preview of the AppBar shows the flexible space in the Android template but not my code.
EDIT: When I click on the reference for "?attr/actionBarSize" in the template it navigates to a different line in android SDK's values.xml, which starts with <declare-styleable name="AppCompatTheme">. The same line of code in my app references a different line starting with<declare-styleable name="Theme">.
Screenshots:
<?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:layout_height="match_parent"
android:background="#color/white"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="#+id/item_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:scrollbars="vertical" />
</LinearLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom|right"
android:layout_marginBottom="#dimen/activity_vertical_margin"
android:layout_marginRight="#dimen/activity_horizontal_margin"
android:src="#drawable/ic_add"
app:backgroundTint="#color/colorPrimary" />
</android.support.design.widget.CoordinatorLayout>
You must add
android:layout_paddingBottom="?attr/actionBarSize
Instead of
android:layout_marginBottom="?attr/actionBarSize
This works for me