可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
When i'm click on my drawer toggle i'm 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>
回答1:
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>
回答2:
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…
回答3:
in my case, because DrawerLayout attr: tools:openDrawer="start"
i added android:layout_gravity="start"
for the second element
<?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" android:fitsSystemWindows="true" tools:openDrawer="start"> <firstElement layout="@layout/app_bar_main" android:layout_width="match_parent" android:layout_height="match_parent" /> <secondElement android:layout_gravity="start" android:layout_width="match_parent" android:layout_height="match_parent" /> </android.support.v4.widget.DrawerLayout>
回答4:
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.
回答5:
If you check more closely, you will notice that there are indeed two top level elements: LinearLayout and fragment.
回答6:
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>