I wanted to implement FrameLayout with toolbar for scrolling_view_behaviour.
But when I set layout_height of FrameLayout to match_parent, it overflows as shown in the picture below:
this is my layout file:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.NewsActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
>
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
style="#style/Widget.AppCompat.Toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:titleTextColor="#fff" />
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:id="#+id/flFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:layout_insetEdge="start">
<fragment
android:id="#+id/navHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/news_nav_graph" />
</FrameLayout>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottomNavigationView"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_gravity="bottom"
android:background="#fff"
app:layout_behavior="#string/hide_bottom_view_on_scroll_behavior"
app:layout_insetEdge="bottom"
app:menu="#menu/bottom_navigation_menu" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
I am sorry if this question is repeated or silly, I couldn't find anything which could solve my problem. Thanks in advance
You can remove attributes which refer to ConstraintLayout because you are not using one here. Also the FrameLayout. Adding margin to bottom of Fragment will set it in proper way.
<androidx.coordinatorlayout.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">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
style="#style/Widget.AppCompat.Toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:titleTextColor="#fff" />
</com.google.android.material.appbar.AppBarLayout>
<fragment
android:id="#+id/navHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="112dp"
app:defaultNavHost="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:navGraph="#navigation/news_nav_graph"
tools:ignore="FragmentTagUsage" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottomNavigationView"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_gravity="bottom"
android:background="#fff"
app:menu="#menu/bottom_navigation_menu" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
As you can see i have added
android:layout_marginBottom="112dp"
But if you add 56dp to it, it will put bottom 56dp layout behind BottomNavigationView. To avoid that inside child fragments which are in other layouts just add more 56dp to it.
Related
How do I include a bottom action bar into my activity_main.xml layout. The bottom action bar comes with a floating action button and both views have to be under the coordinator layout– Here it is:
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.google.android.material.bottomappbar.BottomAppBar
android:id="#+id/bottom_app_bar"
style="#style/Widget.MaterialComponents.BottomAppBar.Colored"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:fabCradleMargin="0dp"
app:fabCradleRoundedCornerRadius="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="#menu/bottom_app_bar_menu" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Layout for the activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.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" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" >
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable"/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/nav_header"
app:menu="#menu/menu_nav" />
</androidx.drawerlayout.widget.DrawerLayout>
The activity_main.xml layout above includes a tab layout and a viewpager for swiping.
I suggest to use the ConstraintLayout to organize your whole View. The BottomNavigationView or BottomAppBar need to be inserted below the Viewpager. Follow along my code to see the hierarchy:
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".MainActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
tools:ignore="MissingConstraints">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"/>
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable"/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/navigationView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="#menu/bottom_navigation"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/nav_header"
app:menu="#menu/menu_nav"/>
</androidx.drawerlayout.widget.DrawerLayout>
In the result you see the BottomNavigationView (I added the menu to make sure you see something, like Fragment 1, Fragment 2 etc..):
I am using the following xml code. The problem is the bottom navigation view is overlapping some portion of the last item of the framelayout. Is there a way i could solve this problem?
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activities.MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:menu="#menu/bottom_navigation"
android:background="?android:attr/windowBackground" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
simple solution is you should set android:paddingBottom for FrameLayout to size of BottomNavigationView's height
I feel like I've tried everything to resolve this but I can't figure out how to have a Coordinatorlayout containing an bottom app bar and a constraintlayout that contains a swipe refreshlayout without the refresh layout overlapping the bottom app bar.
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:background="#color/colorWhite"
tools:context=".departures.DeparturesActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:background="#color/colorWhite"
tools:context=".departures.DeparturesActivity">
<RelativeLayout-with-some-stuff-in-it/>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/departures_swiperefresh_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="0dp">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/departures_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:paddingLeft="#dimen/md_keylines"
android:paddingTop="#dimen/md_keylines"
android:paddingRight="#dimen/md_keylines"
android:paddingBottom="#dimen/md_keylines" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/departures_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:backgroundTint="#color/colorAccent"
app:layout_anchor="#id/bottomAppBar"
app:srcCompat="#drawable/ic_add"
app:tint="#color/colorWhite" />
<com.google.android.material.bottomappbar.BottomAppBar
android:id="#+id/bottomAppBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:backgroundTint="#color/colorPrimary"
app:fabAlignmentMode="end"
app:fabCradleMargin="4dp"
app:fabCradleRoundedCornerRadius="16dp"
app:fabCradleVerticalOffset="4dp"
app:popupTheme="#style/ThemeOverlay.MaterialComponents.Light"
app:theme="#style/ThemeOverlay.MaterialComponents.Dark.ActionBar" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
The SwipeRefreshLayout will overlap the bottom app bar and I cant quite figure out why.
Part of the problem is the fact that the UI designer seems to indicate that the constraintlayout expands way below the coordinatorLayout.
This is due of the padding added here to push the layout below the actionbar.
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".departures.DeparturesPresenter">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="#+id/contentFrame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="?android:attr/actionBarSize" />
</androidx.constraintlayout.widget.ConstraintLayout>
so I can't figure out how to align my bottom navigation in a LinearLayout under a RecyclerView. The items are RecyclerView:
<?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="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CategoryActivity">
<android.support.design.widget.AppBarLayout
android:theme="#style/AppTheme.AppBarOverlay"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_category"
android:layout_margin="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</android.support.v7.widget.RecyclerView>
<android.support.design.widget.BottomNavigationView
android:id="#+id/nav_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground"
android:layout_alignParentBottom="true"
app:menu="#menu/bottom_nav_menu"/>
</LinearLayout>
The navigation should be always at the bottom.
Okay, here is your layout, it should work as you expected
<?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">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
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>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_category"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/nav_view"
android:layout_below="#+id/appbar"
android:layout_margin="8dp"
android:orientation="vertical" />
<android.support.design.widget.BottomNavigationView
android:id="#+id/nav_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="?android:attr/windowBackground"
app:menu="#menu/menu_navigation" />
</RelativeLayout>
Not sure but try adding this:
android:layout_gravity="bottom"
If you don't want to change to RelativeLayout, set this attribute to the RecyclerView:
android:layout_weight="1"
This way the RecyclerView will take all the available space pushing the BottomNavigationView to the bottom.
You Can't adjust your BottomNavigationView properly inside LinearLayout. If there are so many items in your RecyclerView then BottomNavigationView will be hidden at the bottom. So you must use RelativeLayout to align it at the bottom and other layouts above of BottomNavigationView. Please check the bellow modified 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">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
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>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_category"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/nav_view"
android:layout_below="#+id/appbar"
android:layout_margin="8dp"
android:orientation="vertical" />
<android.support.design.widget.BottomNavigationView
android:id="#+id/nav_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="?android:attr/windowBackground"
app:menu="#menu/menu_navigation" />
</RelativeLayout>
Building main app layout that should have:
1) ConstraintLayout as root - because its new and trending changer of RelativeLayout
2) AppBarLayout with toolbar inside
3) BottomNavigationView at the bottom ofc
4) FAB at bottom right above BNV
5) And FrameLayout - container for my fragments that must be between AppBarLayout and BottomNavigationView.
I cant position my FrameLayout. It appears only match_parent with full device size or 0dp.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/appbar_padding_top"
android:theme="#style/AppTheme.AppBarOverlay"
app:layout_constraintTop_toTopOf="#+id/frame_container">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_weight="1"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay"
app:title="#string/app_name">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:layout_constraintTop_toTopOf="parent">
</FrameLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/floatingActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:clickable="true"
android:focusable="true"
app:layout_constraintBottom_toTopOf="#+id/navigation"
app:layout_constraintEnd_toEndOf="parent"
app:srcCompat="#drawable/ic_home_black_24dp" />
<android.support.design.widget.BottomNavigationView
android:id="#+id/navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#color/primary"
app:elevation="8dp"
app:itemIconTint="#color/icons"
app:itemTextColor="#color/icons"
app:layout_constraintBottom_toBottomOf="#+id/frame_container"
app:layout_insetEdge="bottom"
app:menu="#menu/navigation" />
</android.support.constraint.ConstraintLayout>
Set constraintTop and constraintBottom like this:
<FrameLayout
android:id="#+id/frame_container"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:layout_constraintTop_toBottomOf="#+id/appbar"
app:layout_constraintBottom_toTopOf="#+id/navigation">
And also edit the constraints of the other Views