1

I am trying to make new app and at the same time learn Kotlin and use newer features of Android.

In my main_activity I try to create a navigation menu and a toolbar which should always be present (I think it is Single Activity Pattern I try to use).

When I try to close the menu, the app crashes because it cannot find a drawer with gravity left/start.

java.lang.IllegalArgumentException: No drawer view found with gravity LEFT

This is the 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/navigation_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/camera_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/black">

        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/main_app_bar_layout"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:theme="@style/AppTheme.AppBarOverlay"
            app:layout_constraintTop_toTopOf="parent">

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/main_toolbar"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@android:color/holo_blue_light"
                app:popupTheme="@style/AppTheme.PopupOverlay" />

        </com.google.android.material.appbar.AppBarLayout>

        <com.google.android.material.navigation.NavigationView
            android:id="@+id/main_navigation"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:layout_gravity="start"
            app:headerLayout="@layout/navigation_header"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/main_app_bar_layout"
            app:menu="@menu/navigation_menu" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.drawerlayout.widget.DrawerLayout>

If I instead remove the ConstraintLayout it works:

<?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/navigation_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true">
        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/main_app_bar_layout"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:theme="@style/AppTheme.AppBarOverlay"
            app:layout_constraintTop_toTopOf="parent">

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/main_toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="@android:color/holo_blue_light"
                app:popupTheme="@style/AppTheme.PopupOverlay" />

        </com.google.android.material.appbar.AppBarLayout>

        <com.google.android.material.navigation.NavigationView
            android:id="@+id/main_navigation"
            android:layout_marginTop="?attr/actionBarSize"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            app:headerLayout="@layout/navigation_header"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/main_app_bar_layout"
            app:menu="@menu/navigation_menu" />
</androidx.drawerlayout.widget.DrawerLayout>

Note that I have to add marginTop to the navigation view and height to the action bar. As I understand it, ConstraintLayout should be very convenient and easily adjust to different screen sizes.

In this particular case, it is not super hard to get the margins right, but for many other cases it can be hard.

Is there a way of using constraint layouts with navigation view and what is the problem here?

El_Loco
  • 1,716
  • 4
  • 20
  • 35
  • What view among the above do you want to use as a Drawer Layout? Could you please clarify that. I don't think Constraint layout is at fault here. I use Drawer Layout and Constraint layout together so there is no issues as such. – che10 Jun 05 '21 at 07:59
  • Please try this, you will get your answer from this [link](https://stackoverflow.com/a/27352273/16129074) – Nitz_with_u Jun 05 '21 at 07:59

1 Answers1

1

From what I can understand, the issue currently is your <com.google.android.material.navigation.NavigationView also resides inside the ConstraintLayout while you need it outside.

Here is the changed XML that I believe you need.

<?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/navigation_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/camera_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/black">

        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/main_app_bar_layout"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:theme="@style/AppTheme.AppBarOverlay"
            app:layout_constraintTop_toTopOf="parent">

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/main_toolbar"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@android:color/holo_blue_light"
                app:popupTheme="@style/AppTheme.PopupOverlay" />

        </com.google.android.material.appbar.AppBarLayout>

    </androidx.constraintlayout.widget.ConstraintLayout>

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/main_navigation"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="?android:actionBarSize"
        android:layout_gravity="start"
        app:headerLayout="@layout/navigation_header"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/main_app_bar_layout"
        app:menu="@menu/bottom_nav_bar_provider" />

</androidx.drawerlayout.widget.DrawerLayout>

Notice that I have moved out your NavigationView and assigned it a top margin of ?android:actionBarSize as you needed.

It was just the order of Views that was messed up. ConstraintLayout is pretty solid.

che10
  • 2,176
  • 2
  • 4
  • 11
  • Thanks, what is that forces you to have the Navigation View outside? – El_Loco Jun 05 '21 at 08:13
  • For `Navigation View` to be part of `Drawer Layout` it needs to be a direct child of it. When you put it inside `ConstraintLayout` the hierarchy becomes `DrawerLayout -> ConstraintLayout -> NavigationView` and thus not a direct child. So no properties of `DrawerLayout` stay applicable. – che10 Jun 05 '21 at 08:15