2015-02-20 4 views
3

У меня есть работа с навигационным ящиком. если устройство пользователя таблицы и ориентация пейзаж - не нужно, чтобы закрыть лоток, нажав на пункт в ящике:Как предотвратить закрытие выдвижного ящика прикосновения вне выдвижного ящика

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

Он работает. Но если пользователь прикасается к экрану снаружи открытого выдвижного ящика - закрытие ящика. Использование DrawerLayout.LOCK_MODE_LOCKED_OPEN непригодно, потому что мне нужно сохранить функции скольжения ящика. Как предотвратить закрытие выдвижного ящика для навигации, когда пользователь прикасается за пределы выдвижного ящика?

Пожалуйста, помогите.

+1

Просто так вы знаете, что это противоречит [Руководствам Android] (https: //developer.androi d.com/design/patterns/navigation-drawer.html) _When расширяется навигационный ящик, пользователь может отклонить его в одном из четырех способов: Прикосновения содержания вне панели навигации Смахивающих налево в любом месте экран (включая край прокрутки справа) Прикосновение к значку/заголовку приложения в панели действий Нажатие назад_ –

+1

Я согласен, пользователь ожидает такого поведения, когда его заберут, они будут злиться. –

+0

Спасибо за ответы. Я понимаю это, но это требование продукта. –

ответ

1

На основании другого ответа, который я написал 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

Упрощенная версия ответа Noundla, который работает для меня. Я написал свой пользовательский ящик, который расширяет 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); 
0

это очень просто использовать ваш экземпляр ящика, чтобы предотвратить

1. осуществлять DrawerLayout.DrawerListener

2. добавить один оператор внутри этого метода мы

@Override 
public void onDrawerOpened(View drawerView) { 
    drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);//DrawerLayout instance 
} 
Смежные вопросы