У меня есть активность (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, чтобы узнать, почему я получил ошибку.
Если вы находитесь в первом фрагменте и вам нужно перейти ко второму фрагменту, это должно работать: findNavController().navigate(R.id. action_FirstFragment_to_SecondFragment)
navController = Navigation.findNavController(activity, R.id.nav_host_fragment)
Я в fragment
first fragment
. Я не могу использовать то, что вы предлагаете. Я пробовал это: NavHostFragment.findNavController(FirstFragment.this).navigate(R.id.action_FirstFragment_to_SecondFragment);
, но я получаю ту же ошибку.
При использовании компонентов архитектуры навигации 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).navigate(R.id.action_FirstFragment_to_SecondFragment);
Я вижу, позвольте мне проверить это
Я попробовал то, что вы предложили при переходе с 3th
на 1st
, но это не сработало. Поэтому я попробовал с FragmentManager
. Но знайте, что я хочу использовать/выучить NavController
. Я просто не мог.
@carl теперь, когда вы запускаете приложение, FirstFrag > SecondFrag
(в этом нет проблем), но FirstFrag > ThirdFrag > FirstFrag > SecondFrag
(проблема здесь), верно?
приложение запускается. может перемещаться из 1
в 2
, из 2
в 1 back to
2`, из 2
в 3
и из 3
в 1
. Все это без вопросов. Когда я нажимаю floatingactionbutton
для перемещения 1
> 3
, все в порядке (используя FragmentManager
). Но проблемы начинаются отсюда, не может 3
> 1
(пришлось использовать FragmentManager
)
Не уверен, что это может дать некоторые подсказки. Я не вижу других ошибок в предоставленном вами коде.
Это не связано с моей проблемой. Я заменил каждый NavHostFragment.findNavController(fragment) .navigate(R.id.action_...);
на fragmentManager
и все в порядке. Я не знаю, почему эта проблема с NavController
!!!!
Я принял ваш ответ, потому что вы были на правильном пути. Моя проблема была: Я ЗАБЫЛ ПОСТАВИТЬ ОДНО ДЕЙСТВИЕ. Смотрите мой nav_graph.xml
. Я забыл action_FirstFragment_to_ThirdFragment
. Поэтому мне пришлось использовать FragmentManager
, и начались проблемы. Теперь я могу перемещаться по всем фрагментам с помощью NavController
.
Спасибо @carl .. Я обновлю его в ответе, чтобы он мог помочь кому-то еще по всему миру .. Удачного кодирования 😊
при использовании компонента навигации вы не должны обрабатывать транзакции самостоятельно, вместо этого вы определяете действия между каждым фрагментом, а затем получаете доступ к ним напрямую, как это
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
, который вы показали, такой же, как у меня.
Я могу использовать NavHostFragment.findNavController(FirstFragment.this) .navigate(R.id.action_FirstFragment_to_SecondFragment);
, но мне это не подходит.
мой плохой, вы должны добавить this.findNavController(), отредактируете его в ответе, и да, навигационный график такой же, как у вас, потому что он правильный
ваш findNavContoller()
реализован так:public static NavController findNavController(@NonNull Fragment fragment) { View view = fragment.getView(); if (view != null) { return Navigation.findNavController(view); } return null; }
не могли бы вы написать это в своем вопросе? не пишите код в комментариях
val navController = Navigation.findNavController(requireActivity(), R.id.fragment_container)
navigate.navigate(R.id.fragment)
проверьте это, может быть, это поможет вам github.com/sunil-singh-chaudhary/…