как реализовать условную навигацию в компонентах архитектуры навигации

Как реализовать условную навигацию в новом компоненте архитектуры навигации?

В настоящее время у меня есть одно действие с LoginFragment и HomeFragment. Основываясь на определенном login_flag, я использовал любой фрагмент из MainActivity. Поскольку LoginFragment вызывается только один раз, я установил для startDestination значение HomeFragment, и Navigation загрузит этот HomeFragment. есть ли способ проверить login_flag до того, как навигация загрузит HomeFragment.


person Shashi Kiran    schedule 23.05.2018    source источник


Ответы (3)


Вот как я работаю с условной навигацией:

  1. Установите HomeFragment в качестве начального пункта назначения.
  2. Создайте глобальное действие для LoginFragment.

    <action
        android:id="@+id/action_global_loginFragment"
        app:destination="@id/loginFragment"
        app:launchSingleTop="false"
        app:popUpTo="@+id/nav_graph"
        app:popUpToInclusive="true" />
    
  3. Выполните условную навигацию внутри onViewCreated:

    // HomeFragment.kt
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    
        if(!appAuth.isAuthenticated()) {
            view.findNavController().navigate(R.id.action_global_loginFragment)
        }
    }
    
person maxbeaudoin    schedule 06.02.2019
comment
Он выполняет необходимый переход, но на моем экране входа в систему все еще отображается стрелка назад на панели действий. Есть идеи, как от этого избавиться? - person Aleks N.; 22.03.2019
comment
@AleksN. да, вам нужно определить несколько домашних пунктов назначения, чтобы компонент навигации понимал, что возвращаться не к чему. Добавьте экран входа в систему к набору пунктов назначения. См. stackoverflow.com/a/53390772/79152. - person maxbeaudoin; 22.03.2019
comment
Мой пользовательский интерфейс застревает при переходе к исходному фрагменту из глобального фрагмента с использованием этого подхода. Можешь мне помочь? - person Mustufa Ansari; 28.02.2021
comment
@MustufaAnsari, как вернуться назад? Лучший способ перенаправления после входа в систему - это вставить LoginFragment следующим образом navController.popBackStack(). Также попробуйте дважды проверить / отладить вашу условную логику и поэкспериментировать с popUpTo и popUpToInclusive. С тех пор, как я ответил на этот вопрос, Jetpack претерпел значительные изменения, и, хотя этот ответ все еще актуален, код, возможно, потребуется обновить с учетом текущих передовых практик. Например, теперь вы должны использовать классы safeargs и Direction. - person maxbeaudoin; 31.05.2021

Вы можете добавить прослушиватель навигации внутри своей активности и оттуда перейти к LoginFragment в зависимости от ваших условий, например:

findNavController(nav_host_fragment).addOnNavigatedListener { controller, destination ->
        when(destination.id) {
            R.id.HomeFragment-> {
             if(someCondition) {
               //Navigate to LoginFragment
             }

        }
    }
person Alex    schedule 24.05.2018
comment
У такого подхода есть одна проблема. Если вы вызовете NavController.navigate(R.id.destinationId), когда ваше приложение работает в фоновом режиме, вы получите сообщение об ошибке: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState Это ошибка в компоненте архитектуры навигации? - person Alexey Podolian; 04.06.2018
comment
Зачем вам вызывать навигацию, если ваше приложение работает в фоновом режиме? - person Alex; 04.06.2018
comment
Например, я запускаю приложение на устройстве, но оно заблокировано по таймауту (или по другой причине). Затем я нажимаю Run app в Android Studio. Android Studio запустила приложение, а затем вылетает из-за этого исключения. - person Alexey Podolian; 04.06.2018
comment
Вы также можете застрять в бесконечной петле. Например, если ваше условие loggedIn = false - ›тогда переход к фрагменту входа в систему. controller.navigation (...) снова вызовет addOnNavigatedListener перед переходом к цели. - person Erkan; 25.07.2020

Я хотел бы добавить, что есть codelab на сайте developer.android.com для с этой целью.

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

<action
    android:id="@+id/next_action"
    app:popUpTo="@id/home_dest">
</action>

Затем, условно, вы можете установить onClickListeners в своем коде:

view.findViewById<Button>(R.id.navigate_action_button)?.setOnClickListener(
    Navigation.createNavigateOnClickListener(R.id.next_action, null)
)
person cslotty    schedule 07.04.2021