在我的應用程式中,我使用了單個活動并使用了一些片段!
我想首先顯示SplashFragment并檢查用戶令牌,如果存在則打開HomeFragment否則打開RegisterFragment!
我寫了下面的代碼,但是注冊用戶后顯示下面的錯誤!
日志錯誤:
java.lang.IllegalArgumentException: Navigation action/destination my.app:id/actionSplashToHome cannot be found from the current destination Destination(my.app:id/registerFragment) label=fragment_register class=my.app.ui.register.RegisterFragment
at androidx.navigation.NavController.navigate(NavController.kt:1536)
at androidx.navigation.NavController.navigate(NavController.kt:1468)
at androidx.navigation.NavController.navigate(NavController.kt:1450)
at androidx.navigation.NavController.navigate(NavController.kt:1433)
at my.app.ui.splash.SplashFragment$onViewCreated$1$1.emit(SplashFragment.kt:43)
at my.app.ui.splash.SplashFragment$onViewCreated$1$1.emit(SplashFragment.kt:38)
at my.app.utils.UserInfo$getUserToken$$inlined$map$1$2.emit(Emitters.kt:224)
at kotlinx.coroutines.flow.internal.SafeCollectorKt$emitFun$1.invoke(SafeCollector.kt:15)
at kotlinx.coroutines.flow.internal.SafeCollectorKt$emitFun$1.invoke(SafeCollector.kt:15)
at kotlinx.coroutines.flow.internal.SafeCollector.emit(SafeCollector.kt:77)
at kotlinx.coroutines.flow.internal.SafeCollector.emit(SafeCollector.kt:59)
at androidx.datastore.core.SingleProcessDataStore$data$1$invokeSuspend$$inlined$map$1$2.emit(Collect.kt:137)
at kotlinx.coroutines.flow.FlowKt__LimitKt$dropWhile$1$1.emit(Limit.kt:37)
at kotlinx.coroutines.flow.StateFlowImpl.collect(StateFlow.kt:398)
at kotlinx.coroutines.flow.StateFlowImpl$collect$1.invokeSuspend(Unknown Source:15)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
注冊片段代碼:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//InitViews
binding.apply {
//Submit
submitBtn.setOnClickListener { it ->
val name = nameEdt.text.toString()
val email = emailEdt.text.toString()
val password = passwordEdt.text.toString()
//Validation
if (name.isNotEmpty() || email.isNotEmpty() || password.isNotEmpty()) {
body.name = name
body.email = email
body.password = password
viewModel.registerUser(body)
viewModel.registerUser.observe(viewLifecycleOwner) { itResponse ->
Log.e("UserInfoLog","1 : " itResponse.email.toString())
lifecycle.coroutineScope.launchWhenCreated {
userDataStore.saveUserToken(itResponse.email.toString())
Log.e("UserInfoLog","2 : " itResponse.email.toString())
findNavController().navigateUp()
}
}
} else {
Snackbar.make(it, getString(R.string.fillAllFields), Snackbar.LENGTH_SHORT).show()
}
SplashFragment 代碼:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//Check user token
lifecycle.coroutineScope.launchWhenCreated {
delay(2000)
userDataStore.getUserToken().collect {
if (it.isEmpty()) {
findNavController().navigate(R.id.actionSplashToRegister)
} else {
findNavController().navigate(R.id.actionSplashToHome)
}
}
}
}
導航代碼:
<?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/nav_main"
app:startDestination="@id/splashFragment">
<fragment
android:id="@ id/splashFragment"
android:name="my.app.ui.splash.SplashFragment"
android:label="fragment_splash"
tools:layout="@layout/fragment_splash">
<action
android:id="@ id/actionSplashToRegister"
app:destination="@id/registerFragment"
app:enterAnim="@anim/nav_default_enter_anim"
app:exitAnim="@anim/nav_default_exit_anim"
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
app:popExitAnim="@anim/nav_default_pop_exit_anim" />
<action
android:id="@ id/actionSplashToHome"
app:destination="@id/homeFragment"
app:enterAnim="@anim/nav_default_enter_anim"
app:exitAnim="@anim/nav_default_exit_anim"
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
app:popExitAnim="@anim/nav_default_pop_exit_anim"/>
</fragment>
<fragment
android:id="@ id/registerFragment"
android:name="my.app.ui.register.RegisterFragment"
android:label="fragment_register"
tools:layout="@layout/fragment_register">
<action
android:id="@ id/actionRegisterToHome"
app:destination="@id/homeFragment" />
</fragment>
<fragment
android:id="@ id/homeFragment"
android:name="my.app.ui.home.HomeFragment"
android:label="fragment_home"
tools:layout="@layout/fragment_home">
<action
android:id="@ id/action_homeFragment_to_detailFragment"
app:destination="@id/detailFragment" />
</fragment>
<fragment
android:id="@ id/favoriteFragment"
android:name="my.app.ui.favorite.FavoriteFragment"
android:label="fragment_favorite"
tools:layout="@layout/fragment_favorite" />
<fragment
android:id="@ id/searchFragment"
android:name="my.app.ui.search.SearchFragment"
android:label="fragment_search"
tools:layout="@layout/fragment_search" />
<fragment
android:id="@ id/detailFragment"
android:name="my.app.ui.detail.DetailFragment"
android:label="fragment_detail"
tools:layout="@layout/fragment_detail" />
</navigation>
我該如何解決?
uj5u.com熱心網友回復:
看起來由于某種原因findController()仍在使用目的地。RegisterFragment
我猜根本原因是因為執行緒混淆findController()了它仍然認為你在RegisterFragment.
作為深入挖掘執行緒管理之前的解決方法,您可以嘗試對導航布局檔案中的actionSplashToHomea進行操作。Global Action只需將該動作移到fragment標簽之外,然后此導航檔案中的任何片段都可以使用此動作。
<?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/nav_main"
app:startDestination="@id/splashFragment">
<fragment
android:id="@ id/splashFragment"
android:name="my.app.ui.splash.SplashFragment"
android:label="fragment_splash"
tools:layout="@layout/fragment_splash">
<action
android:id="@ id/actionSplashToRegister"
app:destination="@id/registerFragment"
app:enterAnim="@anim/nav_default_enter_anim"
app:exitAnim="@anim/nav_default_exit_anim"
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
app:popExitAnim="@anim/nav_default_pop_exit_anim" />
</fragment>
<action
android:id="@ id/action_global_splash_ToHome"
app:destination="@id/homeFragment"
app:enterAnim="@anim/nav_default_enter_anim"
app:exitAnim="@anim/nav_default_exit_anim"
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
app:popExitAnim="@anim/nav_default_pop_exit_anim"/>
<fragment
android:id="@ id/registerFragment"
android:name="my.app.ui.register.RegisterFragment"
android:label="fragment_register"
tools:layout="@layout/fragment_register">
<action
android:id="@ id/actionRegisterToHome"
app:destination="@id/homeFragment" />
</fragment>
<fragment
android:id="@ id/homeFragment"
android:name="my.app.ui.home.HomeFragment"
android:label="fragment_home"
tools:layout="@layout/fragment_home">
<action
android:id="@ id/action_homeFragment_to_detailFragment"
app:destination="@id/detailFragment" />
</fragment>
<fragment
android:id="@ id/favoriteFragment"
android:name="my.app.ui.favorite.FavoriteFragment"
android:label="fragment_favorite"
tools:layout="@layout/fragment_favorite" />
<fragment
android:id="@ id/searchFragment"
android:name="my.app.ui.search.SearchFragment"
android:label="fragment_search"
tools:layout="@layout/fragment_search" />
<fragment
android:id="@ id/detailFragment"
android:name="my.app.ui.detail.DetailFragment"
android:label="fragment_detail"
tools:layout="@layout/fragment_detail" />
</navigation>
無需更改 Splashfragment 中的代碼,仍可使用findNavController().navigate(R.id.action_global_splash_ToHome)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/440828.html
上一篇:Flutter/Android:您上傳的APK具有活動[...]但沒有'android:exported'屬性。出口=“真”不作業
