NavGraph & ViewModel получает сброс при каждом изменении конфигурацииAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 NavGraph & ViewModel получает сброс при каждом изменении конфигурации

Сообщение Anonymous »

Я использую одно приложение для активности, где у вас есть экран для всплеска, используя новый API экрана Splash, используется для демонстрации экрана Splash до тех пор, пока пользователь входит в систему или нет, если пользователь входит Фрагмент входа в систему, проблема, проблема в том, что у меня есть поля ввода в фрагменте клиента, но когда изменение ориентации все поля сброшены из -за сброса ViewModel, приведенного в график вложенного навигации, и одобрительно, что график NAV сбрасывается при каждом изменении конфигурации, которое сбрасывает ViewModel, так что состояние исчезает, если я охватываю его на работу, но я не хочу, чтобы я не хочу, чтобы я не хочу, чтобы я не хочу, чтобы все было, я не хочу, чтобы все было, я не хочу, чтобы все было, я не хочу, чтобы все было, я не хочу, чтобы все было. Изменения с моим ViewModel, приведенным на вложенном графике

Код: Выделить всё

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
Я также попробовал это https://developer.android.com/guide/nav ... onditional

Но у меня нет основного фрагмента, я всегда открываю приложение либо на фрагменте клиента, либо фрагмент логина, который я сталкивался с множеством проблем с подход к статье 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
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»