Disable DrawerLayout's scrim touch gesture

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-02 10:31:34

问题


I need to disable touch gesture on the scrim (the red highlighted part). I want to dismiss the drawer only with the swipe.

The issue is that when the drawer layout is open and I need to select an element from the ListView below the red highlighted part, what's happend is that the drawer get closed and only at this point I can select an element from the ListView.

I need to select the element from the ListView directly, also when the Drawer is opened


回答1:


You have to create custom drawer for that like this

public class CustomDrawer extends DrawerLayout {



    public CustomDrawer(Context context) {
        super(context);

    }

    public CustomDrawer(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

    }

    public CustomDrawer(Context context, AttributeSet attrs) {
        super(context, attrs);

    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        if(isDrawerOpen(Gravity.START)){
            if(event.getX() > getChildAt(1).getWidth()){
                return false;
            }
        }
        return super.onInterceptTouchEvent(event);
    }

}

Note : getChildAt(1) should be that child to whom you have given gravity as "start" and whose width determines the width of opening drawer.

I hope this should solve your problem




回答2:


I asked an answered a question here:
How to vary between child and parent view group touch events

The parent (drawer) ontouchevent is being fired, rather than the child, listview.

I have also answered a similar problem here:

https://stackoverflow.com/a/28180281/3956566

You need to manage your touch events so it is handled by the child. You need to use an onInterceptTouchEvent and return false.

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    // returning false means the child will handle the touch event.
    return false;
}

You then manage you touchevent for the list view:

@Override
public boolean onTouchEvent(MotionEvent ev) {
    // This method will only be called if the touch event was intercepted in 
    // onInterceptTouchEvent
    // TODO Select your listview item.

}

You can also determine what type of touch event is taking place eg, scrolling and determine whether the child or parent will manage the event.

Managing Touch Events in a ViewGroup

I've added this quote from here Understanding Android Input Touch Events System Framework (dispatchTouchEvent, onInterceptTouchEvent, onTouchEvent, OnTouchListener.onTouch):

The root view starts dispatching the event down to its children. Let’s presume that we have this hierarchy:

A – ViewGroup1 (parent of B).
B – ViewGroup2 (parent of C).
C – View (child of B)
– receives a touch/tap/click. Now the root view will call A.dispatchTouchEvent(). Now the job of a ViewGroup.dispatchEvent() (not View.dispatchEvent()) is to find out all the child views and view groups whose bounds contain the touch point coordinates (using a hit testing algorithm). When it figures out a list of relevant children, it starts dispatching the events to them by calling their dispatchTouchEvent().

Here’s an important piece though. Before the dispatchTouchEvent() is called on the children, the A.dispatchTouchEvent() will first call A.onInterceptTouchEvent() to see if the view group is interested in intercepting the event and handling the subsequent gesture by itself (scrolling is a good use case where a fling on B should lead to scrolling on A). The method onInterceptTouchEvent() is only available on view groups (as they’re the one who can be parents/containers with the requirement to intercept touch events) that can sort of keep an eye on the event and hijack it by returning true. If it returns false then dispatching continues as usual, i.e., B.dispatchTouchEvent() (child) will be called. But on returning true, this is what’ll happen:

ACTION_CANCEL will be dispatched to all the children.
All the subsequent gesture events (till ACTION_UP/ACTION_CANCEL) will be consumed by the event listeners (OnTouchListener.onTouch()) if defined, else the event handler A.onTouchEvent() at A’s level.
A.onInterceptTouchEvent() itself will be never called again.

With this diagram:

Let me know if you need more explanation.




回答3:


just add android:clickable="true" to drawer menu.



来源:https://stackoverflow.com/questions/31718082/disable-drawerlayouts-scrim-touch-gesture

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!