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 fragmentstarts), и когда я нажимаю на него, я открываю 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, чтобы узнать, почему я получил ошибку.


comment
проверьте, возможно, это поможет вам github.com/sunil-singh- Чаудхари /   -  person Sunil Chaudhary    schedule 17.12.2020
comment
Если вы находитесь в первом фрагменте и вам нужно перейти ко второму фрагменту, просто это должно сработать: findNavController (). Navigate (R.id. Action_FirstFragment_to_SecondFragment)   -  person ACR    schedule 17.12.2020


Ответы (3)


При использовании компонентов архитектуры навигации NavController отвечает за транзакцию фрагмента и управляет обратным стеком, а не Support 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 на навигационном графике.

person Zain    schedule 17.12.2020
comment
Я пробовал, но получаю ту же ошибку. Помните, что я нахожусь в the first fragment и хочу пойти в second fragment. Я тоже пробовал: NavHostFragment.findNavController(FirstFragment.this).navigate(R.id.action_FirstFragment_to_SecondFragment); - person carl; 17.12.2020
comment
Понятно, позволь мне проверить - person Zain; 17.12.2020
comment
Я пробовал то, что вы предлагали, по переходу с 3th на 1st, но это не сработало. Поэтому попробовал с FragmentManager. Но знаю, что я хочу использовать / изучить NavController. Я просто не мог. - person carl; 17.12.2020
comment
@carl сейчас, когда вы запускаете приложение, FirstFrag > SecondFrag (в этом нет проблем), но FirstFrag > ThirdFrag > FirstFrag > SecondFrag (проблема здесь), верно? - person Zain; 17.12.2020
comment
приложение запускается. может переходить с 1 на 2, с 2 на 1 back to 2` и с 2 на 3 и с 3 на 1. Все это без проблем. Когда я нажимаю floatingactionbutton для перемещения 13, все в порядке (с использованием FragmentManager). Но проблемы начинаются отсюда, не может 31 (пришлось использовать FragmentManager) - person carl; 17.12.2020
comment
Не уверен, что это может дать некоторые подсказки .. Я не вижу других ошибок в предоставленном вами коде - person Zain; 17.12.2020
comment
Это не связано с моей проблемой. Я заменил каждый NavHostFragment.findNavController(fragment) .navigate(R.id.action_...); на fragmentManager, и все в порядке. Я не знаю, почему эта проблема с _3 _ !!!! - person carl; 17.12.2020
comment
Я принял твой ответ, потому что ты был на правильном пути. Моя проблема заключалась в следующем: Я ЗАБЫЛ ПРОВЕРИТЬ ОДНО ДЕЙСТВИЕ. Смотрите мой nav_graph.xml. Я забыл action_FirstFragment_to_ThirdFragment. Поэтому мне пришлось использовать FragmentManager, и проблемы начались. Теперь я могу перемещаться по всем фрагментам с помощью NavController. - person carl; 17.12.2020
comment
Спасибо @carl .. Я обновлю его в ответе, чтобы он мог помочь кому-то еще по всему миру .. Удачного кодирования ???? - person Zain; 17.12.2020

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

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>
person Mahmoud Omara    schedule 17.12.2020
comment
Вы используете Kotlin. Я не хочу заниматься транзакциями в одиночку. Пришлось это сделать (у меня не работает!). А что такое findNavController() ?. nav_graph, который вы показали, он такой же, как у меня. - person carl; 17.12.2020
comment
Я могу использовать NavHostFragment.findNavController(FirstFragment.this) .navigate(R.id.action_FirstFragment_to_SecondFragment);, но мне это не подходит. - person carl; 17.12.2020
comment
мой плохой, вы должны добавить this.findNavController (), отредактируете его в ответе, и да, навигационный график такой же, как ваш, потому что он правильный - person Mahmoud Omara; 17.12.2020
comment
ваш findNavContoller() реализован так: public static NavController findNavController(@NonNull Fragment fragment) { View view = fragment.getView(); if (view != null) { return Navigation.findNavController(view); } return null; } - person carl; 17.12.2020
comment
не могли бы вы написать это в своем вопросе? не пишите код в комментариях - person Mahmoud Omara; 17.12.2020

person    schedule
comment
Я нахожусь в fragment first fragment. Я не могу использовать то, что вы предлагаете. Я пробовал это: NavHostFragment.findNavController(FirstFragment.this).navigate(R.id.action_FirstFragment_to_SecondFragment);, но получаю то же самое. - person carl; 17.12.2020