gothamgreen gothamgreen - 3 years ago 140
Android Question

Why is scrolling in NavigationView dependent on outside xml elements?

I'm placing a table of contents menu inside a right-sided NavigationView. Here is my code that works:

<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"
android:layout_gravity="right"
tools:openDrawer="start">

<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">

<android.support.v7.widget.Toolbar
android:id="@+id/top_nav_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>

<!-- The main content gets loaded in here. -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/grandparent_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="my.Activity">

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</LinearLayout>

<android.support.design.widget.NavigationView
android:id="@+id/toc_drawer_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
android:fitsSystemWindows="true"
app:headerLayout="@layout/burger_menu_header"
app:theme="@style/TableOfContents_TextAppearance"
app:menu="@menu/burger_menu_drawer_items"
>
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>


In a previous version of the code, I had the NavigationView above the main content-holding LinearLayout. Like this:

<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"
android:layout_gravity="right"
tools:openDrawer="start">

<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">

<android.support.v7.widget.Toolbar
android:id="@+id/top_nav_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>

<android.support.design.widget.NavigationView
android:id="@+id/toc_drawer_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
android:fitsSystemWindows="true"
app:headerLayout="@layout/burger_menu_header"
app:theme="@style/TableOfContents_TextAppearance"
app:menu="@menu/burger_menu_drawer_items"
>
</android.support.design.widget.NavigationView>

<!-- The main content gets loaded in here. -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/grandparent_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="my.Activity">

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</LinearLayout>

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


In that version, the system (both on an emulator and hardware test device) displayed the right-sided drawer, and displayed the first few elements of the menu, but I could not scroll to the bottom of the menu. The scroll bar would appear if I turned it on manually in the xml code, but it just didn't know there was any content beyond the immediately visible.

My question is why? What is the drawing logic behind the scenes that makes the scrolling magic work?

For completeness, burger_menu_header.xml looks like this:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/toc_nav_bar"
android:gravity="bottom"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/nav_header_vertical_spacing"
android:text="Table of Contents"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"/>
</LinearLayout>


and burger_menu_drawer_items.xml looks like:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/nav_chapter_0"
android:icon="@drawable/ic_radio_button_unchecked_black_24dp"
android:title="Introduction"/>

<item
android:id="@+id/nav_chapter_1"
android:icon="@drawable/ic_radio_button_unchecked_black_24dp"
android:title="Chapter 1 - The Adventure"/>
<item
android:id="@+id/nav_chapter_2"
android:icon="@drawable/ic_radio_button_unchecked_black_24dp"
android:title="Chapter 2 - Our Heroes Go Sailing"/>
<item
android:id="@+id/nav_chapter_3"
android:icon="@drawable/ic_radio_button_unchecked_black_24dp"
android:title="Chapter 3 - The Ship Is LostAtSeaFarAway"/>
<item
android:id="@+id/nav_chapter_4"
android:icon="@drawable/ic_radio_button_unchecked_black_24dp"
android:title="Chapter 4 - Skipper Wins!"/>
<item
android:id="@+id/nav_chapter_5"
android:icon="@drawable/ic_radio_button_unchecked_black_24dp"
android:title="Chapter 5"/>
<item
android:id="@+id/nav_chapter_6"
android:icon="@drawable/ic_radio_button_unchecked_black_24dp"
android:title="Chapter 6"/>
<item
android:id="@+id/nav_chapter_7"
android:icon="@drawable/ic_radio_button_unchecked_black_24dp"
android:title="Chapter 7"/>
<item
android:id="@+id/nav_chapter_8"
android:icon="@drawable/ic_radio_button_unchecked_black_24dp"
android:title="Chapter 8"/>
<item
android:id="@+id/nav_chapter_9"
android:icon="@drawable/ic_radio_button_unchecked_black_24dp"
android:title="Chapter 9"/>
<item
android:id="@+id/nav_chapter_10"
android:icon="@drawable/ic_radio_button_unchecked_black_24dp"
android:title="Chapter 10"/>
<item
android:id="@+id/nav_chapter_11"
android:icon="@drawable/ic_radio_button_unchecked_black_24dp"
android:title="Chapter 11 - No Way Is This Happening, She Cried"/>
<item
android:id="@+id/nav_chapter_12"
android:icon="@drawable/ic_radio_button_unchecked_black_24dp"
android:title="Chapter 12 - The End?"/>
<item
android:id="@+id/nav_chapter_13"
android:icon="@drawable/ic_radio_button_unchecked_black_24dp"
android:title="Chapter 13 - But Wait..."/>
<item
android:id="@+id/nav_chapter_14"
android:icon="@drawable/ic_radio_button_unchecked_black_24dp"
android:title="Chapter 14 - But Wait..."/>
<item
android:id="@+id/nav_chapter_15"
android:icon="@drawable/ic_radio_button_unchecked_black_24dp"
android:title="Chapter 14 - Nah, It Was Nothing"/>
</menu>

Sam Sam
Answer Source

It is about

Z-Index

Gothamgreen.

<item num1
<item num2 is above 1
<item num3 is above 2

So it is important that the item that needs touch or focus gets the touch or focus. This is determined first by z-index. In the example above item 3 has the greatest z-index and gets first attempt at handling the touch before it is passed to item 2 and then if item 2 doesn't handle the touch it will go to item 1.

So imagine you had

<content>
<drawerNav>

drawerNav gets first attempt to handle touch and will open/close etc. on touch or swipe. if not needing to handle it will pass through to content view.

now let's consider

<drawerNav>
<content>

content is full screen and will consume touch everytime and never pass through to the drawer, so the drawer will only work from the hamburger menu and not the swipe, and even that is iffy.

So as you can see it has to do with touch handling order via zindex.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download