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>
Ответы
Ответ 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"/>