Java.lang.IllegalStateException ConstraintLayout не имеет набора NavController для фрагмента

У меня есть активность (main) с тремя фрагментами (первый, второй и третий). Я включил 3 фрагмента в свою активность (activity_main.xml), используя <include layout = "@layout/content_main"/>. content_main.xml использует FragmentContainerView с id = nav_host_fragment. А это мой nav_graph.xml:

<navigation xmlns:android = "http://schemas.android.com/apk/res/android"
    xmlns:app = "http://schemas.android.com/apk/res-auto"
    xmlns:tools = "http://schemas.android.com/tools"
    android:id = "@+id/nav_graph"
    app:startDestination = "@id/FirstFragment">

    <fragment
        android:id = "@+id/FirstFragment"
        android:name = "com.example.makegroups.FirstFragment"
        android:label = "@string/first_fragment_label"
        tools:layout = "@layout/fragment_first">

        <action
            android:id = "@+id/action_FirstFragment_to_SecondFragment"
            app:destination = "@id/SecondFragment" />
    </fragment>

    <fragment
        android:id = "@+id/SecondFragment"
        android:name = "com.example.makegroups.SecondFragment"
        android:label = "@string/second_fragment_label"
        tools:layout = "@layout/fragment_second">

        <action
            android:id = "@+id/action_SecondFragment_to_FirstFragment"
            app:destination = "@id/FirstFragment" />
        <action
            android:id = "@+id/action_SecondFragment_to_ThirdFragment"
            app:destination = "@id/ThirdFragment" />
    </fragment>

    <fragment
        android:id = "@+id/ThirdFragment"
        android:name = "com.example.makegroups.ThirdFragment"
        android:label = "@string/third_fragment_label"
        tools:layout = "@layout/fragment_third">

        <action
            android:id = "@+id/action_ThirdFragment_to_FirstFragment"
            app:destination = "@id/FirstFragment" />
    </fragment>
</navigation>

У меня есть floatingactionbuttonв моей деятельности (first fragmentзапускается первой), и когда я нажимаю на нее, я открываю third fragment. На third fragment у меня есть кнопка (далее), чтобы перейти к first fragment, и когда я нажимаю на нее, я возвращаюсь к first fragment, используя:

Fragment frg = new FirstFragment();
FragmentManager fm = requireActivity().getSupportFragmentManager();

Теперь (пока я нахожусь в first fragment) я нажимаю кнопку next (еще одна кнопка для перехода к second fragment), затем приложение вылетает. Я нашел эту ошибку:

java.lang.IllegalStateException: View androidx.constraintlayout.widget.ConstraintLayout{c9572fa V.E...... ........ 0,0-1440,2112} does not have a NavController set

Почему я получаю эту ошибку? -Я попробовал эти предложения здесь, безуспешно.

Я использую Java.

Обновлено: Прочитайте последний комментарий с @Zain, чтобы узнать, почему я получил ошибку.

проверьте это, может быть, это поможет вам github.com/sunil-singh-chaudhary/…

Sunil Chaudhary 17.12.2020 11:11

Если вы находитесь в первом фрагменте и вам нужно перейти ко второму фрагменту, это должно работать: findNavController().navigate(R.id. action_FirstFragment_to_SecondFragment)

ACR 17.12.2020 13:46
3
2
3 311
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

navController = Navigation.findNavController(activity, R.id.nav_host_fragment)

Я в fragmentfirst fragment. Я не могу использовать то, что вы предлагаете. Я пробовал это: NavHostFragment.findNavController(FirstFragment.this).naviga‌​te(R.id.action_First‌​Fragment_to_SecondFr‌​agment);, но я получаю ту же ошибку.

carl 17.12.2020 10:45
Ответ принят как подходящий

При использовании компонентов архитектуры навигации NavController отвечает за транзакцию фрагментов и управление обратным стеком вместо поддержки FragmentManager.

Итак, вместо того, чтобы совершать традиционные транзакции framgnet с FragmentManager

Вы можете перейти от ThridFragment к первому:

 Navigation.findNavController(requireView()).navigate(R.id.action_ThirdFragment_to_FirstFragment);

Где action_ThirdFragment_to_FirstFragment — это идентификатор действия, которое вы определили в графе навигации для перехода от ThridFragment к FirstFragment.

ОБНОВЛЯТЬ:

Как обсуждалось в комментариях, помимо замены FragmentManager на NavController во всех действиях; есть еще одна проблема:

Отсутствует действие action_FirstFragment_to_ThirdFragment на навигационном графике.

Я пробовал, но получаю ту же ошибку. Помните, что я в the first fragment и хочу в second fragment. Я тоже пробовал это: NavHostFragment.findNavController(FirstFragment.this).naviga‌​te(R.id.action_First‌​Fragment_to_SecondFr‌​agment);

carl 17.12.2020 10:51

Я вижу, позвольте мне проверить это

Zain 17.12.2020 10:57

Я попробовал то, что вы предложили при переходе с 3th на 1st, но это не сработало. Поэтому я попробовал с FragmentManager. Но знайте, что я хочу использовать/выучить NavController. Я просто не мог.

carl 17.12.2020 11:08

@carl теперь, когда вы запускаете приложение, FirstFrag > SecondFrag (в этом нет проблем), но FirstFrag > ThirdFrag > FirstFrag > SecondFrag (проблема здесь), верно?

Zain 17.12.2020 11:30

приложение запускается. может перемещаться из 1 в 2, из 2 в 1 back to 2`, из 2 в 3 и из 3 в 1. Все это без вопросов. Когда я нажимаю floatingactionbutton для перемещения 1 > 3, все в порядке (используя FragmentManager). Но проблемы начинаются отсюда, не может 3 > 1 (пришлось использовать FragmentManager)

carl 17.12.2020 11:41

Не уверен, что это может дать некоторые подсказки. Я не вижу других ошибок в предоставленном вами коде.

Zain 17.12.2020 12:00

Это не связано с моей проблемой. Я заменил каждый NavHostFragment.findNavController(fragment) .navigate(R.id.action_...); на fragmentManager и все в порядке. Я не знаю, почему эта проблема с NavController!!!!

carl 17.12.2020 12:12

Я принял ваш ответ, потому что вы были на правильном пути. Моя проблема была: Я ЗАБЫЛ ПОСТАВИТЬ ОДНО ДЕЙСТВИЕ. Смотрите мой nav_graph.xml. Я забыл action_FirstFragment_to_ThirdFragment. Поэтому мне пришлось использовать FragmentManager, и начались проблемы. Теперь я могу перемещаться по всем фрагментам с помощью NavController.

carl 17.12.2020 14:59

Спасибо @carl .. Я обновлю его в ответе, чтобы он мог помочь кому-то еще по всему миру .. Удачного кодирования 😊

Zain 17.12.2020 15:25

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

override fun onCreate(){
  val navController = this.findNavController()
  button.setOnClickListener{
     navController.navigate(R.id.action_FirstFragment_to_SecondFragment, null)
  }
}

и ваш nav_graph должен быть таким

<navigation xmlns:android = "http://schemas.android.com/apk/res/android"
xmlns:app = "http://schemas.android.com/apk/res-auto"
xmlns:tools = "http://schemas.android.com/tools"
android:id = "@+id/nav_graph"
app:startDestination = "@id/FirstFragment">

<fragment
    android:id = "@+id/FirstFragment"
    android:name = "com.example.makegroups.FirstFragment"
    android:label = "@string/first_fragment_label"
    tools:layout = "@layout/fragment_first">

    <action
        android:id = "@+id/action_FirstFragment_to_SecondFragment"
        app:destination = "@id/SecondFragment" />
</fragment>

<fragment
    android:id = "@+id/SecondFragment"
    android:name = "com.example.makegroups.SecondFragment"
    android:label = "@string/second_fragment_label"
    tools:layout = "@layout/fragment_second">

    <action
        android:id = "@+id/action_SecondFragment_to_FirstFragment"
        app:destination = "@id/FirstFragment" />
    <action
        android:id = "@+id/action_SecondFragment_to_ThirdFragment"
        app:destination = "@id/ThirdFragment" />
</fragment>

<fragment
    android:id = "@+id/ThirdFragment"
    android:name = "com.example.makegroups.ThirdFragment"
    android:label = "@string/third_fragment_label"
    tools:layout = "@layout/fragment_third">

    <action
        android:id = "@+id/action_ThirdFragment_to_FirstFragment"
        app:destination = "@id/FirstFragment" />
</fragment>

Вы используете Kotlin. Я не хочу сам заниматься транзакциями. Мне пришлось это сделать (у меня это не работает!). А что такое findNavController()?. Тот nav_graph, который вы показали, такой же, как у меня.

carl 17.12.2020 13:09

Я могу использовать NavHostFragment.findNavController(FirstFragment.this) .navigate(R.id.action_FirstFragment_to_SecondFragment);, но мне это не подходит.

carl 17.12.2020 13:23

мой плохой, вы должны добавить this.findNavController(), отредактируете его в ответе, и да, навигационный график такой же, как у вас, потому что он правильный

Mahmoud Omara 17.12.2020 13:45

ваш findNavContoller() реализован так:public static NavController findNavController(@NonNull Fragment fragment) { View view = fragment.getView(); if (view != null) { return Navigation.findNavController(view); } return null; }

carl 17.12.2020 14:05

не могли бы вы написать это в своем вопросе? не пишите код в комментариях

Mahmoud Omara 17.12.2020 14:35
val navController = Navigation.findNavController(requireActivity(), R.id.fragment_container)
navigate.navigate(R.id.fragment)

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