Как выйти из приложения при обратном нажатии в не начальном пункте назначения? - PullRequest
0 голосов
/ 09 февраля 2019

Скажем, у меня есть график навигации, подобный этому:

---------      ---------
| Home  | ---->| Other |
---------      ---------
    |
    |
    V
---------
| Login |
---------

Если пользователь не вошел в систему, я должен показать экран входа в систему, прежде чем он сможет продолжить.Согласно документам , я проверяю, вошел ли пользователь в систему HomeFragment.Если нет, я открываю LoginFragment.Пока все хорошо.

Но если пользователь нажимает обратно LoginFragment, я хочу, чтобы приложение завершилось.Но поскольку LoginFragment не является пунктом назначения, он просто откроет HomeFragment, что снова откроет LoginFragment.

В настоящее время я закрываю приложение, переопределив onBackPressed() на хосте Activityи finish() Activity, если текущим пунктом назначения является LoginFragment.

Но это кажется хакерским.Я предполагаю, что это должен быть довольно распространенный сценарий навигации.Итак, есть ли «идиоматический» способ сделать это?

Ответы [ 4 ]

0 голосов
/ 22 августа 2019

Возможно, не полностью отвечает на вопрос, но все же может быть полезной информацией для тех, кто, как я, новичок в реализации архитектуры навигации

Это классическая проблема, когда у вас есть «условный» поток.

В настоящее время я обдумываю ту же проблему и могу поделиться своими советами по ее решению.

Если речь шла не о «обратной навигации», а о переносе пользователя на определенный экран, но в то же время об очисткеbackstack, это было бы сделано с использованием

findNavController().popBackStack(R.id.login, true)

Подробнее об этом можно прочитать здесь .

Но еслипользователь нажимает обратно в LoginFragment, я хочу, чтобы приложение завершало работу

То, что вы не упомянули, это то, какую кнопку «назад» вы используете, но думали, чтобы ее решить. Принципы навигации объясняет очень хорошо.

Давайте поговорим о кнопке «Вверх» на панели действий

Что вы не упомянули, но я столкнулся с тем, что вы можете столкнуться с кнопкой «вверх» на панели действийв отличие от кнопки «назад» системы внизу.

Кнопка «Вверх» не должна появляться в вашем случае, поскольку экран входа в систему подобен месту назначения вашего приложения, а кнопка «Вверх» никогда не выходит из приложения.

Но если по какой-то причине вам придется это переопределить, то вы можете сделать это, переопределив onOptionsItemSelected()

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    if (item.itemId == android.R.id.home) {
        finish()
    }
    return super.onOptionsItemSelected(item)
}

Давайте поговорим о системной кнопке «назад»

Документы по Навигационной архитектуре рассказывают о том, как справиться с «пользовательской навигацией» , и это не очень хакерское решение.Оно работает.

Этот SO Ответ показывает код для справки.

Но есть проблема!OnBackPressListener был введен только в последнем нестабильном выпуске, и если вы не можете обновить app compat до 1.0.2-rc01 (на момент написания), то я могу предложить переопределить onBackPressed() в вашей активности хоста и вызватьonFinish() и он в основном выйдет из приложения.Это то, что вы уже делаете.Но недостатком было бы то, что нажатие на любой экран в этом потоке навигационных графиков приведет к выходу из приложения, если только вы не выполняете пользовательские проверки, чтобы вызывать onFinish(), только когда источником был экран входа в систему.Таким образом, чтобы иметь нестандартную навигацию на уровне фрагментов, Android хочет, чтобы мы использовали OnBackPressListener.

Кроме того, в случае onBackPressed или onOptionsItemSelected, если вы хотите реализовать пользовательское поведениеосновываясь на отдельных экранах, вы можете сделать это, используя пункт назначения.

val currentScreenLabel = navController.currentDestination?.label
currentScreenLabel?.let {
      if (it.contains("Login")) {
            navController.navigateUp(appBarConfiguration)
      }
}
0 голосов
/ 09 февраля 2019

Как вы можете видеть в документации , чтобы переопределить кнопку возврата, вы должны использовать
@Override public boolean onSupportNavigateUp() { return Navigation.findNavController(this, R.id.nav_host_fragment).navigateUp(); }

Я нашел другую документацию , которую вы можете иметьвзгляд.

0 голосов
/ 09 февраля 2019

Это происходит потому, что фрагмент добавлен к BackStack Я думаю.Попробуйте не добавлять LoginFragment в backstack.не звоните addToBackStack() для LoginFragment транзакции.Надеюсь, это поможет вам.

0 голосов
/ 09 февраля 2019

Если вы пользуетесь навигацией с использованием действия, лучший способ завершить ваше старое действие:

        Intent intent = new Intent(getApplicationContext(), YOUR_NEXT_ATCIVITY.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK);
        startActivity(intent);

Затем, когда вы нажмете назад, приложение завершит работу

РЕДАКТИРОВАТЬ Так как вы используете фрагмент, вы найдете то, что вам нужно здесь , хорошая статья о том, как управлять Fragment Stack

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...