Android: onBackPressed () не вызывается при открытии ящика навигации

У меня есть основной вид деятельности, который расположен с двумя ящиками для навигации. Левый всегда доступен, но правый используется для отображения некоторых необходимых списков и выполнения определенных действий. Когда у меня есть определенные фрагменты, загруженные в центр FrameLayout активности, у них есть действия, требующие открытия нужного ящика, и выбор элемента. Все это отлично работает, но я хочу убедиться, что когда нажата кнопка «Назад» или экран закроется за пределами ящика, чтобы ящик был закрыт, заблокирован и загруженный фрагмент удален. Я должен также упомянуть, что этот правый ящик содержит FrameLayout и полагается на фрагменты.

В моей основной деятельности это то, что я называю:

 @Override public void onBackPressed(){ Log.d(TAG, "onBackPressed() called"); if(drawerLayoutRight.isDrawerOpen(drawerFrameRight)){ Log.d(TAG, "----------------------"); drawerLayoutRight.closeDrawer(drawerFrameRight); drawerLayoutRight.setDrawerLockMode(1, drawerFrameRight); ExcerciseList fragment = (ExcerciseList) getFragmentManager().findFragmentById(R.id.right_drawer); FragmentTransaction transaction = getFragmentManager().beginTransaction(); transaction.remove(fragment).commit(); } else { super.onBackPressed(); } } 

Я также пробовал:

 public boolean onKeyDown(int keyCode, KeyEvent event){ if (keyCode == KeyEvent.KEYCODE_BACK) { Log.d(TAG, "onKeyDown called"); return true; } return super.onKeyDown(keyCode, event); } 

Но это тоже не сработало. Всякий раз, когда я нажимаю кнопку «Назад», ящик закрывается, но ни один из этих методов не будет вызван. Но как только ящик закрыт, если нажата кнопка «Назад», эти методы будут вызываться. Мне также было интересно, знает ли кто-нибудь о простом способе обработки клика за пределами ящика. Я полагаю, что могу создать пользовательский DrawerLayout и переопределить drawerClose() или проверить координаты, на которые нажимается событие касания. Просто любопытно, имеет ли кто-нибудь более простой способ.

Solutions Collecting From Web of "Android: onBackPressed () не вызывается при открытии ящика навигации"

Поместите эту строку в свой код:

 mDrawerLayout.setFocusableInTouchMode(false); 

Затем он вызовет ваш перезаписанный onBackPressed() когда вы нажмете кнопку «Назад».

Цитата из вопроса в Force EditText, чтобы потерять фокус при нажатии

«По моему опыту onBackPressed () (по крайней мере, по умолчанию @Override в действии) обычно не запускается при нажатии кнопки« Назад », чтобы закрыть клавиатуру. Насколько мне известно, она срабатывает только тогда, когда Back Press начнет завершение () О текущей деятельности. "

Вероятно, это относится к навигационному ящику.

Это, скорее всего, связано с тем, что текущая «активность» не находится в фокусе при открытии ящика (то же самое с SoftKeyboard), поэтому кнопка «Назад назад» не вызывается.

Я смог решить свою проблему, используя DrawerLayout.DrawerListener . Это работало в моей ситуации, потому что когда нажата кнопка «Назад», ящик все еще закрывался, хотя метод onBackPressed() не вызывался.

@MH сказал: «DrawerLayout (я предполагаю, что это то, что вы используете) будет потреблять событие кнопки« Назад », если ящик открыт».

Хотя в документации я не мог найти явного упоминания об этом; Здесь было несколько упоминаний о кнопке «Назад». К сожалению, это не помогло.

Что сказал @MH, объясняет, почему onBackPressed() не вызывался, когда ящик был открыт, и почему он вызывался, когда он был закрыт.

 drawerLayoutRight.setDrawerListener(this); 

Где drawerLayoutRightDrawerLayout . И мой слушатель выглядит так:

 @Override public void onDrawerClosed(View arg0) { if(drawerLayoutRight.getDrawerLockMode(drawerFrameRight)!= 1){ drawerLayoutRight.setDrawerLockMode(1, drawerFrameRight); } ExcerciseList fragment = (ExcerciseList) getFragmentManager().findFragmentById(R.id.right_drawer); if (fragment != null) { FragmentTransaction transaction = getFragmentManager().beginTransaction(); transaction.remove(fragment).commit(); } } 

onDrawerOpened() , onDrawerSlide() и onDrawerStateChanged() все пустые. Только один из моих ящиков использует слушателя, поэтому мне не нужно проверять представление.

Просто попробуй сделать свою работу или сделать ящик.

 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (KeyEvent.KEYCODE_BACK == keyCode && mDrawerLayout != null && mDrawerLayout.isDrawerOpen(leftDrawerView)) { KeyEventCompat.startTracking(event); return true; } return super.onKeyDown(keyCode, event); } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (KeyEvent.KEYCODE_BACK == keyCode && !event.isCanceled() && mDrawerToggle != null && mDrawerLayout.isDrawerOpen(leftDrawerView)) { mDrawerLayout.closeDrawers(); return true; } return super.onKeyUp(keyCode, event); } 

Проблема, как указал @Alex drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); , кажется, что-то делает с drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); метод.

Ни одно из приведенных выше предложений не помогло мне. Поэтому я хотел написать собственное решение. Я выкопал исходный код DrawerLayout Class и попытался переопределить onKeyDown и onKeyUp , но нажатие кнопки «Назад» не запускается вообще, если режим блокировки LOCK_MODE_LOCKED_CLOSED . Я думаю, что это ошибка.

Поэтому в моем случае мне нужно было только заблокировать левый навигационный ящик, а не правильный. И я закончил вызов drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.START); Этот метод блокирует мой левый навигационный ящик вместо вызова drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); Этот метод, который блокирует оба ящика и вызывает ошибку этой кнопки.

Итак, как резюме, drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); Отключает кнопку «Назад». Может быть, только если у вас есть два ящика для навигации.

После добавления этой кнопки возврата линии вы можете закрыть DrawerLayout .

 mDrawerLayout.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); 

У меня была очень похожая проблема с пустым списком в фрагменте (не будет реагировать на кнопку «Назад», когда список пуст), и некоторые из упомянутых здесь решений помогли мне решить мою проблему.

Фрагмент, вызывающий проблему с помощью «onBackPressed ()»:

 <TextView android:id="@android:id/empty" ... /> <ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="match_parent" /> 

Проблема аналогична тем, что, когда список, возвращаемый адаптером, пуст (@android: id / empty), первое представление (TextView), похоже, не считается «рассматриваемым» как фокусное / сфокусированное представление Android (тогда как Второй вид – ListView – есть).

Таким образом, нажатие кнопки «Назад» не будет регистрироваться просмотром, отображаемым в настоящее время, и не будет улавливаться моим пользовательским кодом в фрагменте (вместо этого непосредственно закрывается действие).

В моем случае добавление следующего в onCreateView решило мою проблему (и позволила кнопке «Назад» нажать на фрагмент, даже если список пуст):

  View view = inflater.inflate(R.layout.fragment_content, container, false); view.setFocusableInTouchMode(true); view.requestFocus(); 

Я знаю, что это немного поздно, но все же … этот ответ поможет другим

 @Override public void onBackPressed() { if (mDrawerLayout.isOpen()) mDrawerLayout.close(); else super.onBackPressed(); } 
 DrawerLayout drawer... @Override public void onBackPressed() { // TODO Auto-generated method stub if(drawer.isDrawerOpen(Gravity.LEFT)){ drawer.closeDrawer(Gravity.LEFT); }else{ super.onBackPressed(); } } 

Я нашел этот ответ отсюда . Он отлично работает на моем коде.