Подтвердить что ты не робот

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() или проверить координаты, которые нажаты на событие касания. Просто любопытно, есть ли у кого более простой способ.

4b9b3361

Ответ 1

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

mDrawerLayout.setFocusableInTouchMode(false);

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

Ответ 2

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

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

Это, вероятно, применимо к ящику навигации так же.

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

Ответ 3

Я смог решить свою проблему, используя 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() все пустые. Только один из моих ящиков использует слушателя, поэтому мне не нужно проверять представление.

Ответ 4

Просто выполните лишнюю операцию или сделайте вывод.

@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);
}

Ответ 5

Проблема, как указал @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); отключает кнопку "Назад", нажмите "как-то". Может быть, только если у вас есть два ящика для навигации.

Ответ 6

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

mDrawerLayout.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); 

Ответ 7

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

Фрагмент, вызывающий проблему с помощью "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();

Ответ 8

DrawerLayout drawer...

@Override
public void onBackPressed() {
    // TODO Auto-generated method stub

    if(drawer.isDrawerOpen(Gravity.LEFT)){
        drawer.closeDrawer(Gravity.LEFT);
    }else{
        super.onBackPressed();
    }
}

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

Ответ 9

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

@Override
public void onBackPressed()
{
  if (mDrawerLayout.isOpen())
  mDrawerLayout.close();
else
  super.onBackPressed();
}