Ответ 1
Поместите эту строку в свой код:
mDrawerLayout.setFocusableInTouchMode(false);
Затем он назовет ваш перезаписанный 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()
или проверить координаты, которые нажаты на событие касания. Просто любопытно, есть ли у кого более простой способ.
Поместите эту строку в свой код:
mDrawerLayout.setFocusableInTouchMode(false);
Затем он назовет ваш перезаписанный onBackPressed()
, когда вы нажмете кнопку "Назад".
Цитата из вопроса в Force EditText, чтобы потерять фокус при нажатии
"По моему опыту onBackPressed() (по крайней мере, по умолчанию @Override в действии) обычно не срабатывает при нажатии кнопки" Назад ", чтобы закрыть клавиатуру. Насколько мне известно, она срабатывает только при нажатии Back Press инициируйте финиш() для текущей активности.
Это, вероятно, применимо к ящику навигации так же.
Это, скорее всего, связано с тем, что текущая "активность" не находится в фокусе при открытии ящика (то же самое с SoftKeyboard), поэтому кнопка "Назад назад" не вызывается.
Я смог решить свою проблему, используя DrawerLayout.DrawerListener
. Это работало в моей ситуации, потому что когда нажата кнопка "Назад", ящик все еще закрывался, хотя метод onBackPressed()
не вызывался.
@MH сказал: "DrawerLayout (я предполагаю, что то, что вы используете) будет потреблять событие кнопки" Назад ", если ящик открыт."
Хотя в документации я не мог найти явного упоминания об этом; было некоторое упоминание о кнопке "Назад" здесь. К сожалению, это не помогло.
Что сказал @MH, объясняет, почему onBackPressed()
не вызывался при открытии ящика и почему он вызывался, когда он был закрыт.
drawerLayoutRight.setDrawerListener(this);
Где drawerLayoutRight
- DrawerLayout
. И мой слушатель выглядит так:
@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 Vasilkov, кажется, что-то делает с помощью метода drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
.
Ни одно из приведенных выше предложений не помогло мне. Поэтому я хотел написать собственное решение. Я выкопал исходный код DrawerLayout Class и попытался переопределить методы onKeyDown
и onKeyUp
, но кнопка Back Button не запускается вообще, если режим блокировки 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();
DrawerLayout drawer...
@Override
public void onBackPressed() {
// TODO Auto-generated method stub
if(drawer.isDrawerOpen(Gravity.LEFT)){
drawer.closeDrawer(Gravity.LEFT);
}else{
super.onBackPressed();
}
}
Я нашел этот ответ от здесь. Он отлично работает на моем коде.
Я знаю, что это немного поздно, но все же... этот ответ поможет другим
@Override
public void onBackPressed()
{
if (mDrawerLayout.isOpen())
mDrawerLayout.close();
else
super.onBackPressed();
}