Новый навигационный компонент из арки с вложенным графиком навигации

У меня есть один случай, и я хочу реализовать его с помощью элемента навигационной системы. Например, у меня есть 2 Nav Graphs (основной и вложенный). Могу ли я вызвать основной график из вложенных и как? пример

Ответы

Ответ 1

Дело в том, чтобы получить правильное NavController для навигации по правильному графику. Давайте рассмотрим этот сценарий как пример:

MainActivity
|- MainNavHost
   |- NavBarFragment
   |  |- NestedNavHost
   |  |  |-NestedContentFragment1
   |  |  |-NestedContentFragment2
   |  |
   |  |- BottomNavigationView
   |
   |- LoginFragment

Основной граф и вложенный граф находятся в отдельных файлах xml: это необходимо, насколько я понял, потому что навигаторы нацелены на разные области макета, поэтому им требуются два разных NavHost. Каждому Navhost необходимо будет ссылаться на свой график по id, что требует, чтобы они находились в разных файлах ресурсов.

Дело в том, что для навигации в определенном графике, мы должны получить ссылку на правообладатель графа: делать это, при вызове Navigation.findNavController(view), то view аргумент является решающим.

Документы говорят, что

NavHostFragments регистрируют свой контроллер навигации в корне своего поддерева просмотра, так что любой потомок может получить экземпляр контроллера с помощью методов класса вспомогательного помощника навигации

Так, например, если внутри NavBarFragment мы пишем

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    navController = Navigation.findNavController(view)
}

здесь view является родителем NestedNavHost (то есть вложенным NavHostFragment), а не потомком, что означает, что findNavController будет искать вверх по течению в дереве и вернет MainNavHost NavController.

Если вместо этого писать

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    val fragmentContainer = view.findViewById<View>(R.id.nestedNavHostFragment)
    navController = Navigation.findNavController(fragmentContainer)
}

где nestedNavHostFragment является идентификатором в теге fragment в макете, мы получаем ссылку на правильный NestedNavHost, потому что представление, которое мы теперь передаем findNavController принадлежит поддереву NestedNavHost.

Аналогично, если вам нужно получить ссылку на главный NavController изнутри NestedContentFragment, вот что мы можем сделать:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    // we can get the innermost NavController using this view,
    // because we are inside its subtree:
    nestedNavController = Navigation.findNavController(view)

    // we can find the outer NavController passing the owning Activity
    // and the id of a view associated to that NavController,
    // for example the NavHostFragment id:
    mainNavController = Navigation.findNavController(activity!!, R.id.mainNavHostFragment)
}

Ответ 2

На самом деле работает, используя

val host: NavHostFragment? = (childFragmentManager.findFragmentById(R.id.main_app_fragment_container)  as NavHostFragment?)

Я могу перемещаться из основного фрагмента

Ответ 3

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

Ответ 4

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

Создайте глобальное действие от вложенного навигационного графа до желаемого пункта назначения в основном навигационном графе (выделено на рисунке ниже)

Пример:

nav graph

<navigation android:id="@+id/main_nav_graph"
     ... >
     <fragment android:id="@+id/fragStart" .../>
     <fragment .../>
     <fragment .../>

     <navigation  android:id="@+id/nested_nav_graph">
           ...

     <!-- Global Action -->
     <action
         android:id="@+id/action_global_start"
         app:destination="@id/fragStart" />
     </navigation>

</navigation>

Для перехода к пункту назначения основного графика используйте

findNavController().navigate(R.id.action_global_start)