Tobias
Tobias

Reputation: 5453

Android DrawerLayout - No drawer view found with gravity

When I click on my drawer toggle I get the following exception:

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

This is my activity_drawer.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    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">

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

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:minHeight="?attr/actionBarSize"
        android:background="?attr/colorPrimary"/>

    <FrameLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <fragment
        android:id="@+id/navigation"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:name="com.xyz.ui.navigation.NavigationFragment"
        tools:layout="@layout/fragment_navigation" />

    </LinearLayout>
</android.support.v4.widget.DrawerLayout>

My fragment_navigation.xml:

<?xml version="1.0" encoding="utf-8"?>
<ListView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="start">

</ListView>

And my list item:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Large Text"
        android:id="@+id/navigation_item_text"
        android:layout_gravity="center_horizontal" />
</LinearLayout>

Upvotes: 47

Views: 66363

Answers (10)

George Vortelinos
George Vortelinos

Reputation: 41

The error fixed after replacing

<fragment
        android:id="@+id/fragmentContainerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.example.MyFragment"/>

with

<androidx.fragment.app.FragmentContainerView
        android:id="@+id/fragmentContainerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start" />

and added Fragment instance to the FragmentContainerView in onCreate()

supportFragmentManager.beginTransaction()
    .add(R.id.fragmentContainerView, MyFragment())
    .commit()

Upvotes: 0

Khaled Inf
Khaled Inf

Reputation: 79

add

android:layout_gravity="start"

to NavigationView

like this

<com.google.android.material.navigation.NavigationView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:headerLayout="@layout/drawer_menu"
    android:layout_gravity="start"
    android:foregroundGravity="right"
    android:id="@+id/nv">

    <include layout="@layout/drawer_menu"/>
</com.google.android.material.navigation.NavigationView>

Upvotes: 5

Sana Ebadi
Sana Ebadi

Reputation: 7220

I solve this problem like this :

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"
    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"
    android:layoutDirection="rtl"
    tools:openDrawer="end"
    >

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

        <include
            layout="@layout/toolbar_main"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <include layout="@layout/content_main" />

    </LinearLayout>

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/navigationView"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:layoutDirection="rtl"
        android:background="@color/white"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/menu_drawer" />

</androidx.drawerlayout.widget.DrawerLayout>

AND IN JAVA:

 if (mDrawerLayout != null && mDrawerLayout.isDrawerOpen(GravityCompat.END)) {
        mDrawerLayout.closeDrawer(GravityCompat.END);
    }

I hope this helps someone!

Upvotes: 2

itzhar
itzhar

Reputation: 13031

in my case, because DrawerLayout attr: tools:openDrawer="start" i added android:layout_gravity="start" for the second element

 <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"
    tools:openDrawer="right"
    tools:context=".map.MapFragment">

<include layout="@layout/fragment_map" />

<FrameLayout
        android:id="@+id/content_frame"
        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="right"
        android:background="@color/white"
        android:fitsSystemWindows="true"
        app:menu="@menu/drawer_view"
        app:headerLayout="@layout/drawer_nav_header"/>

</android.support.v4.widget.DrawerLayout>

Upvotes: 4

Maryam Azhdari
Maryam Azhdari

Reputation: 1319

You should use the same gravity in DrawerLayout and NavigationView: for example: tools:openDrawer="right"in DrawerLayout tag and android:layout_gravity="right" in NavigationView tag

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:openDrawer="right"
    tools:context=".map.MapFragment">

<include layout="@layout/fragment_map" />
<FrameLayout
        android:id="@+id/content_frame"
        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="right"
        android:background="@color/white"
        android:fitsSystemWindows="true"
        app:menu="@menu/drawer_view"
        app:headerLayout="@layout/drawer_nav_header"/>

</android.support.v4.widget.DrawerLayout>

Upvotes: 1

user1474089
user1474089

Reputation: 81

Are you using right to left(RTL) layout? Setting gravity left on RTL layout would throw this exception. This can be fixed by setting gravity start instead of left

Upvotes: 2

Peter Akwa
Peter Akwa

Reputation: 115

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

SOLUTION Assign a layout_gravity = "start" or "left" attribute to one of your DrawerLayout child view if your drawer layout already have a child view. OR Simply create a child view inside your DrawerLayout View and give it a layout_gravity = "start" or "left" attribute. for example

 <?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:id="@+id/mDrawer_Layout"
        tools:context="com.rad5.matdesign.MainActivity">

        <android.support.design.widget.CoordinatorLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <android.support.v4.widget.DrawerLayout
                android:id="@+id/drawer_layout"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                tools:openDrawer="start">

    <!-- Notice that here an image view as a child of the Drawer layout was -->
    <!-- given a layout_gravity="start" -->

                <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="start"/>

            </android.support.v4.widget.DrawerLayout>

            <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.support.v7.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    android:background="?attr/colorPrimary"/>

                <android.support.design.widget.TabLayout
                    android:id="@+id/tabs"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content" />
            </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>

        <android.support.design.widget.NavigationView
            android:id="@+id/nav_view"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:headerLayout="@layout/nav_header"
            app:menu="@menu/menu_navigation_items" />

    </android.support.design.widget.CoordinatorLayout>

Upvotes: 0

Devendra Vaja
Devendra Vaja

Reputation: 3964


Ok. Let me make the things simple and clear here.
What is DrawerLayout?https://developer.android.com/reference/android/support/v4/widget/DrawerLayout.html

DrawerLayout Acts as a top-level container for window content that allows for interactive "drawer" views to be pulled out from the edge of the window. Drawer positioning and layout is controlled using the android:layout_gravity attribute on child views corresponding to which side of the view you want the drawer to emerge from: left or right. (Or start/end on platform versions that support layout direction.) To use a DrawerLayout, position your primary content view as the first child with a width and height of match_parent. Add drawers as child views after the main content view and set the layout_gravity appropriately. Drawers commonly use match_parent for height with a fixed width.


What is DrawerLayout?, In Simple words:
  • The layout supported by Android that allows you to have an overlay screen, called as drawer, over your main screen.
  • DrawerLayout needs childviews to work, similar to the LinearLayout and RelativeLayout.
  • The childview must have either of the property set
    android:layout_gravity="start" OR android:layout_gravity="left"
  • DrawerLayout uses this childView to know from where to start showing the Drawer i.e. From Left to Right or Right to Left. There are countries where the text is read from Right to Left.


Techie Stuff:
  • EVENT#1: ActionBarDrawerToggle.java is set as the drawer listener for the DrawerLayout
  •     DrawerLayout mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
        ActionBarDrawerToggle mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                    toolbar,R.string.navigation_drawer_open,
                    R.string.navigation_drawer_close)
                    mDrawerLayout.setDrawerListener(mDrawerToggle);
        
  • EVENT#2: The user clicks on the Toolbar.navigationIcon that calls the toggle() function
    ActionBarDrawerToggle.java (android-sdk\sources\android-22\android\support\v7\app\ActionBarDrawerToggle.java)
        private void toggle() { 
            if (mDrawerLayout.isDrawerVisible(GravityCompat.START)) {
                mDrawerLayout.closeDrawer(GravityCompat.START); 
            } else {
                mDrawerLayout.openDrawer(GravityCompat.START); 
            } 
        } 
        

    Gravity.java (android-sdk\sources\android-22\android\view\Gravity.java)
    /** Push object to x-axis position at the start of its container,
        not changing its size.*/ 
        public static final int START = RELATIVE_LAYOUT_DIRECTION | Gravity.LEFT; 
        
  • EVENT#3: Toggle() function calls the mDrawerLayout.openDrawer(Gravity.START)
    DrawerLayout.java (support-v4-22.1.1.jar library)
        /*** Open the specified drawer by animating it out of view. **
        @param gravity Gravity.LEFT to move the left drawer or Gravity.RIGHT
        for the right. * GravityCompat.START or GravityCompat.END may also
        be used. */ 
        public void openDrawer(@EdgeGravity int gravity) { 
            final View drawerView = findDrawerWithGravity(gravity); 
            if (drawerView == null) { 
                throw new IllegalArgumentException("No drawer view found with gravity " +
        gravityToString(gravity)); 
            }
            openDrawer(drawerView); 
        }
        
  • EVENT#4: If no childView of the DrawerLayout is set with the layout_gravity="start” or left the No drawer view found with gravity LEFT is thrown.

Solution:

    <android.support.v4.widget.DrawerLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        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">
    <!--This will appear when the drawer is closed (default view)--> 
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"> 
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:minHeight="?attr/actionBarSize"
            android:background="?attr/colorPrimary" /> 
    </LinearLayout> 
    <!-- This will appear when the drawer is opened -->
    <!-- the property,android:layout_gravity, is used internally to identify imageView as the view to be displayed when the drawer is opened -->
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height=" match_parent"
        android:layout_gravity="left"
        android:background="@drawable/img_shree_ganesha" /> 

    </android.support.v4.widget.DrawerLayout>
I hope that helps. Happy Coding…

Upvotes: 20

WindSpirit
WindSpirit

Reputation: 181

The "Android Drawer" needs to be a direct child node of the "DrawerLayout".

In your example above (re: original question example), you only have a single direct child node under "DrawerLayout" ("LinearLayout"), and no drawer view after it.

Move your drawer view out of your LinearLayout and place it after it.

Upvotes: 10

Dmytro
Dmytro

Reputation: 853

From documentation

To use a DrawerLayout, position your primary content view as the first child with a width and height of match_parent. Add drawers as child views after the main content view and set the layout_gravity appropriately. Drawers commonly use match_parent for height with a fixed width.

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    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">

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

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:minHeight="?attr/actionBarSize"
        android:background="?attr/colorPrimary"/>

    <FrameLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    </LinearLayout>

    <fragment
        android:id="@+id/navigation"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="right"
        android:name="com.xyz.ui.navigation.NavigationFragment"
        tools:layout="@layout/fragment_navigation" />

</android.support.v4.widget.DrawerLayout>

Upvotes: 33

Related Questions