Ответ 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)
}