Код: Выделить всё
private val viewModel: CustomerAddressDetailsViewModel by hiltNavGraphViewModels(R.id.new_shipment_wizard_nav_graph)
< /code>
Я также пробовал много вещей, но это не сработало, попытался предотвратить снова установить NavGraph, проверяя на SaveDinStance == NULL, но при изменении ориентации он бросает исключение, здесь - это стек Trace: < /p>
java.lang.IllegalArgumentException: No destination with ID 2131362257 is on the NavController's back stack. The current destination is null
Но у меня нет основного фрагмента, я всегда открываю приложение либо на фрагменте клиента, либо фрагмент логина, который я сталкивался с множеством проблем с подход к статье het at it so Come My Sough NAVGRAPH < /p>
Код: Выделить всё
< /code>
Это мой вложенный график < /p>
< /code>
Это мой Oncreate внутри MainActivity и единственного действия < /p>
override fun onCreate(savedInstanceState: Bundle?) {
val splashScreen = installSplashScreen()
splashScreen.setKeepOnScreenCondition { viewModel.keepSplashScreen }
super.onCreate(savedInstanceState)
enableEdgeToEdge()
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
ViewCompat.setOnApplyWindowInsetsListener(binding.main) { view, windowInsets ->
// Get insets for system bars (status bar, navigation bar)
val systemBarInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
// Get insets for the keyboard
val imeInsets = windowInsets.getInsets(WindowInsetsCompat.Type.ime())
// 1. Apply top padding to the AppBarLayout
binding.appbar.updatePadding(
top = systemBarInsets.top,
left = systemBarInsets.left,
right = systemBarInsets.right,
)
// 2. Calculate the correct bottom padding. It's the max of the keyboard or the navigation bar height.
val bottomPadding = max(imeInsets.bottom, systemBarInsets.bottom)
binding.fragmentContainerView.updatePadding(
left = systemBarInsets.left,
right = systemBarInsets.right,
bottom = bottomPadding
)
// Return the insets to allow children to handle them if needed
windowInsets
}
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.fragmentContainerView) as NavHostFragment
navController = navHostFragment.navController
val graph = navController.navInflater.inflate(R.navigation.nav_graph)
setSupportActionBar(binding.myToolbar)
observeGlobalErrors()
observeLoadingState()
viewModel.checkUserLoggedIn()
setupStartDestination(graph)
viewModel.checkServerStatus()
navController.addOnDestinationChangedListener { _, destination, _ ->
when (destination.id) {
R.id.customerAddressDetailsStep -> {
binding.appbar.isVisible = true
stepper(1, 4)
binding.stepperView.isVisible = true
}
R.id.packagingStepFragment -> {
binding.appbar.isVisible = true
stepper(2, 4)
binding.stepperView.isVisible = true
}
else -> {
binding.appbar.isVisible = false
binding.stepperView.isVisible = false
}
}
}
}
< /code>
Это функция, которая имеет основную навигационную логику < /p>
/** Set up start destination (login or home) before starting connectivity observer */
private fun setupStartDestination(graph: androidx.navigation.NavGraph) {
lifecycleScope.launch {
viewModel.startDestination.collect { destination ->
destination?.let {
graph.setStartDestination(it)
navController.graph = graph
delay(1)
viewModel.keepSplashScreen = false
viewModel.isNavGraphReady = true
observeConnectivity()
val appBarConfiguration = AppBarConfiguration(
setOf(R.id.customerAddressDetailsStep)
)
setupActionBarWithNavController(navController, appBarConfiguration)
}
}
}
}
< /code>
Это ViewModel < /p>
package com.postscanmail.shipper.presentation.main_screen
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.postscanmail.shipper.R
import com.postscanmail.shipper.domain.usecase.server_usecases.CheckServerStatusUseCase
import com.postscanmail.shipper.utils.AppDataStore
import com.postscanmail.shipper.utils.ConnectivityManagerNetworkMonitor
import com.postscanmail.shipper.utils.GlobalErrorEvent
import com.postscanmail.shipper.utils.GlobalErrorHandler
import com.postscanmail.shipper.utils.Result
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class MainViewModel @Inject constructor(
private val appDataStore: AppDataStore,
private val networkMonitor: ConnectivityManagerNetworkMonitor
) : ViewModel() {
var isNavGraphReady = false
var keepSplashScreen: Boolean = true
@Inject
lateinit var checkServerStatusUseCase: CheckServerStatusUseCase
private val _isLoading = MutableStateFlow(false)
val isLoading: StateFlow = _isLoading.asStateFlow()
private val _startDestination = MutableStateFlow(null)
val startDestination: StateFlow = _startDestination
fun showLoading() {
_isLoading.value = true
}
fun hideLoading() {
_isLoading.value = false
}
fun checkUserLoggedIn() {
viewModelScope.launch {
val token = appDataStore.getAccessToken()
_startDestination.value = if (token.isNullOrBlank()) {
R.id.loginFragment
} else {
R.id.new_shipment_wizard_nav_graph
}
}
}
val isOffline: StateFlow = networkMonitor.isOnline
.map(Boolean::not)
.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(5_000),
false
)
fun onRetryClicked(): Boolean {
return networkMonitor.isCurrentlyConnected()
}
fun checkServerStatus() {
viewModelScope.launch {
checkServerStatusUseCase.invoke().collect {
if (it is Result.Success) {
GlobalErrorHandler.postEvent(GlobalErrorEvent.NoError)
}
}
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/797 ... fig-change
Мобильная версия