abstract class BaseViewModel<STATE: Parcelable>( private val savedStateHandle: SavedStateHandle, private val defaultState: STATE): ViewModel() {
private val KEY_STATE = "state"
val state: StateFlow<STATE> = savedStateHandle.getStateFlow(KEY_STATE, defaultState)
protected fun updateState(newState: STATE.() -> STATE) { // see DataStore updateData // get current state savedStateHandle.get<STATE>(KEY_STATE)?.let { state -> // simpan state baru ke savedStateHandle savedStateHandle[KEY_STATE] = newState(state) } }}
@Parcelizedata class MyState( val text: String = ""): Parcelable
@HiltViewModelclass MyViewModel @Inject constructor( savedStateHandle: SavedStateHandle): BaseViewModel<MyState>( savedStateHandle = savedStateHandle, defaultState = MyState()) {
fun updateText(newText: String) { updateState { copy( text = newText ) } }}
@Composablefun MyScreen( viewModel: MyViewModel = hiltViewModel()) {
// Observe state val state by viewModel.state.collectAsStateWithLifecycle()
Box( contentAlignment = Alignment.Center, modifier = Modifier .fillMaxSize() ) { OutlinedTextField( value = state.text, onValueChange = viewModel::updateText ) }}
@AndroidEntryPointclass MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { ComposeResearchTheme { Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { MyScreen() } } } }}Posts · February 2024