Created
          March 12, 2025 06:40 
        
      - 
      
- 
        Save akexorcist/581fef399ae0d7aefa67af51a2eb865c to your computer and use it in GitHub Desktop. 
Revisions
- 
        akexorcist created this gist Mar 12, 2025 .There are no files selected for viewingThis file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,34 @@ @SuppressLint("RestrictedApi") @Composable fun <T : ViewModel> ComposableScopeViewModelProvider( key: String, viewModelFactory: @Composable (key: String) -> T, content: @Composable (viewModel: T) -> Unit, ) { val activity = LocalActivity.current ?: return val viewModelStoreOwner = LocalViewModelStoreOwner.current ?: return val lifecycleOwner = LocalLifecycleOwner.current DisposableEffect(lifecycleOwner) { var isConfigurationChanging = false val observer = LifecycleEventObserver { _, event -> if (event == Lifecycle.Event.ON_DESTROY) { isConfigurationChanging = activity.isChangingConfigurations } } lifecycleOwner.lifecycle.addObserver(observer) onDispose { lifecycleOwner.lifecycle.removeObserver(observer) if (!isConfigurationChanging) { // Replace the ViewModel with an empty one to make the ViewModel clear viewModelStoreOwner.viewModelStore.put( key = key, viewModel = object : ViewModel() { override fun onCleared() = Unit } ) } } } content(viewModelFactory(key)) } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,48 @@ /* * Composable has gone by UI logic: ViewModel and data are cleared * Configuration changes: ViewModel and data still exist. * Application process recreation: Clear ViewModel and data. */ // SectionViewModel.kt class SectionViewModel(private val savedStateHandle: SavedStateHandle) : ViewModel() { val uiState: StateFlow<String?> = savedStateHandle.getStateFlow<String?>( key = "uiState", initialValue = null, ) fun updateValue() { val newValue = UUID.randomUUID().toString() savedStateHandle["uiState"] = newValue } override fun onCleared() { super.onCleared() // Clean up is requires for any saved state value savedStateHandle.keys().forEach { key -> savedStateHandle.remove<Any>(key) } } } // SampleScreen.kt @Composable fun SampleScreen() { var showSection by remember { mutableStateOf<Boolean>(false) /* ... */ if (showSection) { ComposableScopeViewModelProvider( key = "section", factory = { key -> viewModel<SectionViewModel>(key = key) } // Koin library // factory = { key -> koinViewModel<SectionViewModel>(key = key) }, ) { viewModel -> StatefulSection() } } } @Composable fun StatefulSection(viewModel: SectionViewModel) { /* .. */ } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,37 @@ /* * Composable has gone by UI logic: ViewModel and data are cleared. * Configuration changes: ViewModel and data still exist. * Application process recreation: ViewModel cleared, but data still exists. */ // SectionViewModel.kt class SectionViewModel(private val savedStateHandle: SavedStateHandle) : ViewModel() { private val _uiState = MutableStateFlow<String?>(null) val uiState: StateFlow<String?> = _uiState fun updateValue() { val newValue = UUID.randomUUID().toString() _uiState2.update { newValue } } } // SampleScreen.kt @Composable fun SampleScreen() { var showSection by remember { mutableStateOf<Boolean>(false) /* ... */ if (showSection) { ComposableScopeViewModelProvider( key = "section", factory = { key -> viewModel<SectionViewModel>(key = key) } // Koin library // factory = { key -> koinViewModel<SectionViewModel>(key = key) }, ) { viewModel -> StatefulSection() } } } @Composable fun StatefulSection(viewModel: SectionViewModel) { /* .. */ }