Почему у меня есть StackruError при реализации Включить в контроллер навигации?
Файл моего проекта: https://drive.google.com/file/d/11llz7ylWe7ACyLMBbqp6YzugUL8hhImt/view?usp=sharing
поэтому у меня 2 навигационных графика. называется основной навигационный граф, а также граф аутентификации.
Я включаю основной граф в график аутентификации и наоборот, график аутентификации в основной граф.
Я хочу внедрить систему входа в систему, поэтому, когда пользователь успешно вошел в систему, тогда пользователь перейдет к основному действию (которое имеет нижнюю панель навигации и панель инструментов), у действия проверки подлинности отсутствует нижнее представление навигации или фрагмент. вот графики
- основной график навигации:
<?xml version="1.0" encoding="utf-8"?>
<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/navigation_graph"
app:startDestination="@id/destination_home">
<include app:graph="@navigation/auth_graph" />
<fragment android:id="@+id/destination_home" android:name="com.muchammadagunglaksana.navcontroller.HomeFragment"
android:label="Home Judul" tools:layout="@layout/fragment_home">
<action android:id="@+id/action_toAuthActivity" app:destination="@id/auth_graph"/>
</fragment>
<fragment android:id="@+id/destination_camera" android:name="com.muchammadagunglaksana.navcontroller.CameraFragment"
android:label="Camera Judul" tools:layout="@layout/fragment_camera">
<action android:id="@+id/toPhotosDestination" app:destination="@id/destination_photos"/>
</fragment>
<fragment android:id="@+id/destination_photos" android:name="com.muchammadagunglaksana.navcontroller.PhotosFragment"
android:label="Foto Judul" tools:layout="@layout/fragment_photos">
<action android:id="@+id/toHomeDestination" app:destination="@id/destination_home"/>
<argument android:name="numberOfPhotos" app:argType="integer" android:defaultValue="0"/>
</fragment>
<fragment android:id="@+id/destination_settings"
android:name="com.muchammadagunglaksana.navcontroller.SettingsFragment"
android:label="Setting Judul" tools:layout="@layout/fragment_settings"/>
</navigation>
<include app:graph="@navigation/navigation_graph" /> <fragment android:id="@+id/loginFragment" android:name="com.muchammadagunglaksana.navcontroller.LoginFragment" android:label="fragment_login" tools:layout="@layout/fragment_login"> <action android:id="@+id/action_toMainActivity" app:destination="@id/navigation_graph"/> </fragment>
когда кнопка входа нажата в LoginFragment, тогда я использую код ниже:
login_button.setOnClickListener {
Navigation.findNavController(it).navigate(R.id.action_toMainActivity)
}
а также в HomeFragment, когда кнопка выхода из системы нажата, я использую:
logout_button.setOnClickListener {
Navigation.findNavController(it).navigate(R.id.action_toAuthActivity)
}
но я получил stackruerror:
E / AndroidRuntime: ИСКЛЮЧИТЕЛЬНОЕ ИСКЛЮЧЕНИЕ: основной процесс: com.muchammadagunglaksana.navcontroller, PID: 14322 java.lang.StackruError: размер стека 8 МБ в android.support.v4.util.SparseArrayCompat.(SparseArava.ppsu.77).v4.util.SparseArrayCompat.(SparseArrayCompat.java:62) на androidx.navigation.NavGraph.(NavGraph.java:44) на androidx.navigation.NavGraphNavigator.createDestination(NavGraphNavigator.java:54) навигатор и на android createDestination(NavGraphNavigator.java:29) на androidx.navigation.NavInflater.inflate(NavInflater.java:100) на androidx.navigation.NavInflater.inflate(NavInflater.java:80) на androidx.navigation.NavInflafla.infj:128) на androidx.navigation.NavInflater.inflate(NavInflater.java:80) на androidx.navigation.NavInflater.inflate(NavInflater.java:128) на androidx.navigation.NavInflater.inflate(NavInflater.java:80) на androidx.navigation.NavInflater.inflate(NavInflater.java:128) в androidx.navigation.NavInflate r.inflate (NavInflater.java:80) в androidx.navigation.NavInflater.inflate(NavInflater.java:128) в androidx.navigation.NavInflater.inflate(NavInflater.java:80) в androidx.navigation.NavInflafla.inflate (NavInIn.java:128)
na.navcontroller E / JavaBinder:!!! СБОЙ СДЕЛКИ БИНДЕРА!!!
что пошло не так?
1 ответ
<include>
тег является точным эквивалентом копирования / вставки точного содержимого включающего графа вместо <include>
, Имея ваш auth_graph
включить navigation_graph
Вы построили цикл: navigation_graph
содержит auth_graph
который содержит navigation_graph
и навсегда.
Что вам нужно сделать, это удалить <include app:graph="@navigation/navigation_graph" />
от твоего auth_graph
, Потому что ваш auth_graph
уже в пределах navigation_graph
Вам не нужно добавлять его второй раз, но вы можете напрямую ссылаться на любое из этих направлений.
Как сказал @ianhanniballake, когда вы используете <include>
тег, вы копируете все назначения навигационного графа в фактическое. У меня была такая же проблема, поэтому я сделал вот что. Я создал класс util, в котором есть этот метод:
/**
* Search all the destinations in
* the graph to be added. If the
* actual graph doesn't contain
* one of these destinations, is
* added to the actual graph
*
* @param view the actual view (to extract the actual graph and to inflate the new one)
* @param navGraphId the graph destinations to be added
*/
fun addGraphDestinations(view: View, navGraphId : Int) {
// Get the actual navcontroller
val navController = view.findNavController()
// Get the nav inflater
val navInflater = navController.navInflater
// Get the actual graph in use
val actualGraph = navController.graph
// Inflate the new graph
val newGraph = navInflater.inflate(navGraphId)
val list = mutableListOf<NavDestination>()
// Search if there's a new destination to add into the actual graph
newGraph.forEach { destination ->
if(actualGraph.findNode(destination.id) == null) {
list.add(destination)
}
}
list.forEach {
newGraph.remove(it)
actualGraph.addDestination(it)
}
}
Поэтому, когда вам нужно добавить график, вы добавляете его в такой код:
// We have to check if all prospect destinations are already added to the actual graph
NavigationUtils.addGraphDestinations(view, R.navigation.your_graph)
Надеюсь, это кому-то поможет!