«IllegalArgumentException: ID не ссылается на представление внутри этого исключения действия» при вызове findNavController(деятельность, идентификатор) в onViewCreated

Я получаю исключение IllegalArgumentException с сообщением «ID не ссылается на представление внутри этого действия» при вызове findNavController(requireActivity(), R.id.mainNavHostFragment) внутри метода onViewCreated() фрагмента. Фрагмент создается FragmentStateAdapter для ViewPager, и проблема возникает только при возврате в приложение после изменения конфигурации.

NavHostFragment находится в действии фрагмента, и идентификатор правильно указан в вызове findNavController(requireActivity(), R.id.mainNavHostFragment). Проблема возникает только после изменения конфигурации.

Хост навигации в activity_main.xml:

       <fragment
                android:id="@+id/mainNavHostFragment"
                class="androidx.navigation.fragment.NavHostFragment"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginTop="?attr/actionBarSize"
                app:defaultNavHost="true"
                app:navGraph="@navigation/nav_graph" />

Фрагменты onViewCreated:

       override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    navController = try {
        findNavController(view)
    } catch (e: IllegalStateException) {
        findNavController(requireActivity(), R.id.mainNavHostFragment)
    }
    keyboardManager.registerKeyboardConsumer(this)
}

1 ответ

Если вы получаете «IllegalArgumentException: ID не ссылается на представление внутри этого исключения действия» при вызове findNavController(requireActivity(), R.id.mainNavHostFragment) внутри onViewCreated(), возможно, что NavHostFragment еще не был полностью инициализирован .

Это происходит, когда фрагмент воссоздается из-за изменения конфигурации (например, изменения языка системы), потому что иерархия представлений фрагмента уничтожается и создается заново. При воссоздании иерархии представления возможно, что NavHostFragment еще не был воссоздан, поэтому попытка найти его идентификатор в иерархии представления действия приведет к созданию исключения IllegalArgumentException.

Решение 1. Отложите вызов onActivityCreated

Чтобы избежать этой проблемы, вы можете отложить вызов findNavController(requireActivity(), R.id.mainNavHostFragment) до полной инициализации NavHostFragment. Один из способов сделать это — переопределить метод onActivityCreated() в вашем фрагменте и вызвать оттуда findNavController(requireActivity(), R.id.mainNavHostFragment):

      class MyFragment : Fragment() {

private lateinit var navController: NavController

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)

    navController = Navigation.findNavController(requireActivity(), R.id.mainNavHostFragment)
    // Use navController here
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    // Your other initialization code here
}
}

Решение 2. получить navcontroller из фрагмента хоста

Если дочернему фрагменту ViewPager необходимо получить ссылку на NavController из родительского фрагмента NavHostFragment, вы можете получить ее из фрагмента хоста.

Поскольку родительский NavHostFragment является частью графа навигации, вы можете получить ссылку на NavController, просто вызвав findNavController(view) в методе onViewCreated() родительского фрагмента. Затем вы можете передать эту ссылку дочерним фрагментам или сохранить ее в модели представления, которая совместно используется родительским и дочерним фрагментами.

Другие вопросы по тегам