如何通过触摸抽屉外部来防止关闭导航抽屉

时间:2015-02-20 10:02:22

标签: android touch navigation-drawer

我有一个带导航抽屉的活动。如果用户设备是桌子并且方向是横向的 - 我不需要通过点击抽屉中的项目来关闭抽屉:

if (!isTablet || context.getResources().getConfiguration().orientation==1) {
    mDrawerLayout.closeDrawer(Gravity.START);
}

有效。但如果用户触摸屏幕外打开的抽屉 - 抽屉关闭。 使用DrawerLayout.LOCK_MODE_LOCKED_OPEN是不合适的,因为我需要保存抽屉滑动功能。 当用户触摸抽屉外时如何防止关闭导航抽屉?

请帮助。

3 个答案:

答案 0 :(得分:3)

Noundla的简化版本的答案对我有用。我编写了自定义Drawer,它扩展了DrawerLayout并实现了dispatchTouchEvent()方法。

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    if (!this.isDrawerOpen(Gravity.LEFT)) {
        return super.dispatchTouchEvent(event);
    }
    boolean isOutSideClicked = false;
    if (event.getAction() == MotionEvent.ACTION_UP) {
        View content = findViewById(R.id.drawer_view); 
        int[] contentLocation = new int[2];
        content.getLocationOnScreen(contentLocation);
        Rect rect = new Rect(contentLocation[0],
                contentLocation[1],
                contentLocation[0] + content.getWidth(),
                contentLocation[1] + content.getHeight());
        isOutSideClicked = !(rect.contains((int) event.getX(), (int) event.getY()));
    }
    this.setDrawerLockMode(isOutSideClicked ? DrawerLayout.LOCK_MODE_LOCKED_OPEN : DrawerLayout.LOCK_MODE_UNLOCKED);
    return super.dispatchTouchEvent(event);
}

此外,如果您想在抽屉打开时与主要内容片段保持互动,则应在方法的开头添加此行。

getChildAt(0).dispatchTouchEvent(event);

答案 1 :(得分:2)

基于我写的here的其他答案。我修改了代码以适合您的问题。请检查。

详细了解触控层次结构here

应在dispatchTouchEvent()

中覆盖

Activity方法

@Override    
public boolean dispatchTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_UP) {
        if (isDrawerOpen()) { //Your code here to check whether drawer is open or not. 

            View content = findViewById(R.id.drawer); //drawer view id
            int[] contentLocation = new int[2];
            content.getLocationOnScreen(contentLocation);
            Rect rect = new Rect(contentLocation[0],
                contentLocation[1],
                contentLocation[0] + content.getWidth(),
                contentLocation[1] + content.getHeight());

            if (!(rect.contains((int) event.getX(), (int) event.getY()))) {
                isOutSideClicked = true;
            } else {
                isOutSideClicked = false;
            }

        } else {
            return super.dispatchTouchEvent(event);
        }
    } else if (event.getAction() == MotionEvent.ACTION_DOWN && isOutSideClicked) {
        isOutSideClicked = false;
        return super.dispatchTouchEvent(event);
    } else if (event.getAction() == MotionEvent.ACTION_MOVE && isOutSideClicked) {
        return super.dispatchTouchEvent(event);
    }

    if (isOutSideClicked) {
        return true; //restrict the touch event here
    }else{
        return super.dispatchTouchEvent(event);
    }
}

注意:正如问题评论中所述,这违反了Android guidelines。因此,除非是强制性的,否则请尽量避免使用。

答案 2 :(得分:1)

使用抽屉实例非常简单

<强> 1。实现DrawerLayout.DrawerListener

<强> 2。在此方法中添加此单个语句

 @Override
public void onDrawerOpened(View drawerView) {
    drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);//DrawerLayout instance
}