Drawer Layout takes the touch event instead of navigation pane's elements
Asked Answered
R

2

6

My android project contains 2 navigation drawers. One from right side, other from left. It open with click of button using this:

if (mDrawerLayout.isDrawerOpen(mRightDrawerView))
    mDrawerLayout.closeDrawer(mRightDrawerView);
mDrawerLayout.openDrawer(mLeftDrawerView);

Both drawers have custom layouts in them, defined using:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >

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

<include
    android:id="@+id/left_drawer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    layout="@layout/menu_panel" />

<include
    android:id="@+id/right_drawer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="end"
    layout="@layout/search_panel" />

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

The problem is: When I open a drawer and try to capture its click event, (There are buttons and textviews in the drawer layout) the drawer closes instead of responding to click events.

I have also used:

mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
mDrawerLayout.requestDisallowInterceptTouchEvent(true);

I do not want drawer to close on touch event inside it.

I have also tried changing the "clickable" attribute of drawer layout. But no use.

Any help is highly appreciated. Thanks

Rubble answered 16/4, 2014 at 12:49 Comment(0)
D
2

Might be its too late to answer your Question , but it'll help the others , those who are facing the same problem as you..

Set Clickable 'true' to your included layouts i.e your left and right drawer. the clickable event consumes the touch.

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >

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

<include
    android:id="@+id/left_drawer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:clickable="true"
    layout="@layout/menu_panel" />

<include
    android:id="@+id/right_drawer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="end"
    android:clickable="true"
    layout="@layout/search_panel" />

</android.support.v4.widget.DrawerLayout> 
Doerrer answered 10/9, 2014 at 12:46 Comment(0)
M
0

Just to build on the accepted answer, I had a child view that needed to consume (horizontal) swipes instead of just clicks so the accepted answer doesn't work for me. In my case I had a Slider child inside a DrawerLayout. I had to extend the Slider, override onTouchEvent and set parent.requestDisallowInterceptTouchEvent(true):

class DrawerSlider @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : Slider(context, attrs, defStyleAttr) {

@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(event: MotionEvent): Boolean {

    parent.requestDisallowInterceptTouchEvent(true)
    return super.onTouchEvent(event)
}

}

Read up on how touch events are consumed in ViewGroups for details, but in summary any child onTouchEvent will first get passed to its parent and it's up to the parent to decide if the parent needs to consume the event first. For the DrawerLayout it was consuming horizontal swipes action first, consuming left swipes in the DrawerLayout draggers so I could not decrease my Slider value without increasing it first. Right swipes work because the DrawerLayout is fully open so it would pass the touch events down to the Slider without conflict. parent.requestDisallowInterceptTouchEvent(true) resolves this by telling the parent to not consume the touch events from the child. You have to call it with each event because the setting defaults back to false after touch events/actions finish/get cancelled.

Maidenhair answered 22/11, 2020 at 18:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.