Holger
Holger

Reputation: 502

Bottom of NavHostFragment hidden behind BottomNavigationView

I have layout with a nav bar at the bottom and the main content inside a NavHostFragment. Now the bottom of the NavHostFragment is hidden behind the nav bar. How can I fix this?

This is the main layout of the activity:

<?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_height="match_parent"
    android:layout_width="match_parent">

    <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toTopOf="@id/nav_view"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/mobile_navigation" />


    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/nav_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="0dp"
        android:layout_marginEnd="0dp"
        android:background="?android:attr/windowBackground"
        android:layout_alignParentBottom="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:menu="@menu/bottom_nav_menu" />

</androidx.constraintlayout.widget.ConstraintLayout>

And one of the fragments of the nav host:

<?xml version="1.0" encoding="utf-8"?>

<androidx.core.widget.NestedScrollView
    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="wrap_content"
    android:isScrollContainer="true"
    app:layout_constraintTop_toTopOf="parent">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

    </LinearLayout>

</androidx.core.widget.NestedScrollView>

Upvotes: 7

Views: 4419

Answers (6)

Zohab Ali
Zohab Ali

Reputation: 9544

I used LinearLayout as main layout and added weights to the child layouts

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/mobile_navigation"
        android:layout_weight="2"/>

    <com.google.android.material.bottomnavigation.BottomNavigationView
        app:itemIconTint="@drawable/bottom_navigation_selector"
        app:itemTextColor="@drawable/bottom_navigation_selector"
        android:id="@+id/nav_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0"
        android:background="?android:attr/windowBackground"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:menu="@menu/bottom_nav_menu" />

</LinearLayout>

Upvotes: 0

Abhishek Dwarakanath
Abhishek Dwarakanath

Reputation: 81

Try the below layout. You can change the appCustomViewPager to anything which is usable for you.

        <androidx.constraintlayout.widget.ConstraintLayout 
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

<com.impelsys.ebooks.ui.AppCustomViewPager
    android:id="@+id/view_pager"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:background="@color/colorWhite"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    app:layout_constraintBottom_toTopOf="@+id/nav_view"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="1.0"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintVertical_bias="1.0" />

<com.google.android.material.bottomnavigation.BottomNavigationView
    android:id="@+id/nav_view"
    android:layout_width="0dp"
    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_nav_menu" />

</androidx.constraintlayout.widget.ConstraintLayout>

Upvotes: 0

Chandan Pednekar
Chandan Pednekar

Reputation: 555

Set android:layout_height="0dp" for NavHostFragment.

When you want to adjust width / height based on constraints so that they take up remaining space in relation to a constraint with other View, set the width / height to 0dp. Only then the Constraints work.

Upvotes: 0

A J
A J

Reputation: 4632

Add

android:layout_marginBottom="55dp"

in your androidx.navigation.fragment.NavHostFragment

Upvotes: 0

chatlanin
chatlanin

Reputation: 6105

I had the same problem and I found a cure. @ianhanniballake was right, but that is not a final solution. The problem is in value of 'layout_height' of NavHostFragment. You should walk through next 3 steps in activity_main.xml:

  1. Be sure or remove android:paddingTop="?attr/actionBarSize" from root ConstraintLayout
  2. Add app:layout_constraintTop_toBottomOf="@id/nav_host_fragment" to <BottomNavigationView>
  3. Change in <fragment ... NavHostFragment>

    android:layout_height="match_parent"

to

android:layout_height="0dp"
android:layout_weight="1"

=======================

A Little investigation:

Let's create a 'Bottom Navigation Activity'-project from scratch.

Step 0.1:

add background to root of activity_main.xml

android:background="@android:color/holo_green_light"

Step 0.2: change content of fragment_home.xml to this:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/holo_orange_dark">

    <TextView
        android:id="@+id/left_top"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="L_T"
        android:background="#ffcccc"
        android:layout_gravity="start|top"
        android:textSize="120sp" />

    <TextView
        android:id="@+id/right_bottom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="R_B"
        android:background="#ccffcc"
        android:layout_gravity="end|bottom"
        android:textSize="120sp" />
</FrameLayout>

You will see:

Step 1: remove android:paddingTop="?attr/actionBarSize":

Step 2: Add app:layout_constraintTop_toBottomOf="@id/nav_host_fragment" constraint for BottomNavigationView

Step 3 (Final). change height to 0dp and add android:layout_weight="1" for NavHostFragment

PS.Hope this helps for other similar problems

Upvotes: 14

ianhanniballake
ianhanniballake

Reputation: 199805

You're missing a app:layout_constraintTop_toBottomOf="@id/nav_host_fragment" on your nav_view - you need both directions to build a constraint chain:

<com.google.android.material.bottomnavigation.BottomNavigationView
    android:id="@+id/nav_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginStart="0dp"
    android:layout_marginEnd="0dp"
    android:background="?android:attr/windowBackground"
    android:layout_alignParentBottom="true"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@id/nav_host_fragment"
    app:menu="@menu/bottom_nav_menu" />

Of course, there's no reason to use ConstraintLayout for this case - if you have solely vertically stacked, non-overlapping views, you should use a LinearLayout.

Upvotes: 2

Related Questions