我的项目文件:https://drive.google.com/file/d/11llz7ylWe7ACyLMBbqp6YzugUL8hhImt/view?usp=sharing
所以我有2个导航图。称为主导航图和身份验证图。
我将主图包含在auth图中,反之亦然,将auth图包含在主图中。
我想实现登录系统,因此当用户成功登录时,用户将转到主活动(具有底部导航视图和工具栏),而auth活动则没有底部导航视图或片段。这是图
<?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)
}
但是我遇到了stackoverflowerror:
E / Android运行时:致命异常:主要 流程:com.muchammadagunglaksana.navcontroller,PID:14322 java.lang.StackOverflowError:堆栈大小8MB 在android.support.v4.util.SparseArrayCompat。(SparseArrayCompat.java:77) 在android.support.v4.util.SparseArrayCompat。(SparseArrayCompat.java:62) 在androidx.navigation.NavGraph。(NavGraph.java:44) 在androidx.navigation.NavGraphNavigator.createDestination(NavGraphNavigator.java:54) 在androidx.navigation.NavGraphNavigator.createDestination(NavGraphNavigator.java:29) 在androidx.navigation.NavInflater.inflate(NavInflater.java:100) 在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.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.NavInflater.inflate(NavInflater.java:80) 在androidx.navigation.NavInflater.inflate(NavInflater.java:128)
na.navcontroller E / JavaBinder:!!!绑定交易失败!!!
出了什么问题?
答案 0 :(得分:3)
<include>
标记等同于复制/粘贴包含图的确切内容代替<include>
。通过让auth_graph
包含navigation_graph
,您就建立了一个循环:navigation_graph
包含auth_graph
,其中包含navigation_graph
直到永远。
您需要做的是从<include app:graph="@navigation/navigation_graph" />
中删除auth_graph
。由于您的auth_graph
已经在navigation_graph
内,因此您无需再次添加它,但是您可以直接引用这些目的地中的任何一个。
答案 1 :(得分:1)
正如@ianhanniballake所说,当您使用<include>
标记时,会将所有navgraph目标复制到实际的目标中。我有同样的问题,所以我要做的就是这个。我创建了一个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)
希望它对某人有帮助!