Подтвердить что ты не робот

Android DrawerLayout - нет обзора ящика с гравитацией

Когда я нажимаю на переключатель ящика, я получаю следующее исключение:

java.lang.IllegalArgumentException: ящик не отображается с гравитацией ВЛЕВО

Это мой 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>

Мой 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>

И мой элемент списка:

<?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>
4b9b3361

Ответ 1

Из документации

Чтобы использовать DrawerLayout, поместите основной контент в качестве первого ребенка с шириной и высотой match_parent. Добавьте ящики в виде дочерних представлений после основного содержимого и соответствующим образом установите layout_gravity. Ящики обычно используют match_parent для высоты с фиксированной шириной.

<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. Позвольте мне сделать вещи простыми и ясными здесь.   
Что такое DrawerLayout? https://developer.android.com/reference/android/support/v4/widget/DrawerLayout.html  

  DrawerLayout  Действует как контейнер верхнего уровня для содержимого окон, что позволяет   интерактивные "выдвижные" виды, которые необходимо вытащить с края   окно. Позиционирование и расположение ящика контролируется с помощью android:layout_gravity  атрибут на дочерних представлениях, соответствующий той стороне представления, которую вы   хотите, чтобы ящик появился: слева или справа. (Или начать/завершить   версии платформы, поддерживающие направление макета.) Чтобы использовать   DrawerLayout, разместите свой основной контент в качестве первого ребенка с шириной   и высота match_parent. Добавьте ящики в виде дочерних представлений после основного содержимого и установите   layout_gravity соответственно. Ящики обычно используют match_parent для высоты с фиксированной шириной.   

  
Что такое DrawerLayout?, Простыми словами:  
  •   
  • Макет, поддерживаемый Android, который позволяет вам иметь экран наложения, называемый ящиком, над основным экраном.  
  • DrawerLayout нуждается в детском просмотре для работы, аналогично LinearLayout и RelativeLayout.  
  • Childview должен иметь либо набор свойств   
      android:layout_gravity="start" ИЛИ android:layout_gravity="left"    
  • DrawerLayout использует этот childView, чтобы знать , откуда начинать показывать ящик i.e. Слева направо или справа на   Оставил. Есть страны, где текст читается справа налево.     
  

   Techie Stuff:  
  •   
  • СОБЫТИЕ № 1: ActionBarDrawerToggle.java устанавливается в качестве слушателя ящика для 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);
    
   СОБЫТИЕ №2: пользователь нажимает на панель инструментов .navigationIcon, которая вызывает функцию toggle()  
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() вызывает mDrawerLayout.openDrawer(Gravity.START)  
   DrawerLayout.java (библиотека поддержки-v4-22.1.1.jar)   
    /*** 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); 
    }
    
     СОБЫТИЕ № 4: Если ни один childView из DrawerLayout не установлен с помощью layout_gravity="start" или left, вызывается No drawer view found with gravity LEFT.       
  <Б > Решение:
    <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

"Ящик Android" должен быть прямым дочерним элементом node для "DrawerLayout".

В приведенном выше примере (re: исходный вопрос) у вас есть только один прямой дочерний node под "DrawerLayout" ( "LinearLayout" ) и без просмотра ящика после него.

Извлеките вид своего ящика из LinearLayout и поместите его после него.

Ответ 4

в моем случае, потому что DrawerLayout attr: tools:openDrawer="start" я добавил android:layout_gravity="start" для второго элемента

 <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>

Ответ 5

Используете ли вы справа налево (RTL) макет? Установка гравитации, оставленной на RTL-макете, вызвала бы это исключение. Это может быть исправлено установкой силы тяжести вместо левой

Ответ 6

Вы должны использовать ту же силу тяжести в DrawerLayout и NavigationView: например: tools: openDrawer = "right" в теге DrawerLayout и android: layout_gravity = "right" в теге NavigationView

<?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>

Ответ 7

Если вы посмотрите более внимательно, вы заметите, что на самом деле есть два элемента верхнего уровня: LinearLayout и фрагмент.

Ответ 8

java.lang.IllegalArgumentException: не найдено ни одного обзора ящика с гравитацией LEFT

РЕШЕНИЕ Назначьте атрибут layout_gravity = "start" или "left" для одного из ваших дочерних представлений DrawerLayout, если в вашем макете ящика есть дочерний вид. ИЛИ Просто создайте дочерний вид внутри вашего DrawerLayout View и присвойте ему атрибут layout_gravity = "start" или "left" .       например

 <?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>

Ответ 9

U должен использовать ту же силу тяжести в DrawerLayout и NavigationView: например: tools:openDrawer="right" в теге DrawerLayout и android:layout_gravity="right" в теге NavigationView

<include layout="@layout/fragment_map" />
<!-- Layout to contain contents of main body of screen (drawer will slide over this) -->
<FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

<!-- Container for contents of drawer - use NavigationView to make configuration easier -->
<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:fitsSystemWindows="true"
        app:menu="@menu/drawer_view"
        app:headerLayout="@layout/drawer_nav_header"/>