Guy Bieber
08/17/2020, 8:45 PMclass LoginView(
private var dataModel : LoginDataModel
) : Component ()
...
@Composable
override fun view () {
BottomDrawerLayout(
drawerState = dataModel.drawerState,
gesturesEnabled = true,
drawerContent = {
drawerView()
},
bodyContent = {
baseView()
}
)
}
My application model was all defined in one library with @Model.
Now I am trying to move to the recommended porting described in dev12:
class Position(x: Int, y: Int) {
var x by mutableStateOf(x)
var y by mutableStateOf(y)
}
// source of Example is identical to original
@Composable fun Example() {
var p = remember { Position(0, 0) }
PositionChanger(
position=p,
onXChange={ p.x = it }
onYChange={ p.y = it }
)
}
However, if you look at mutableStateOf it says you should use state and stateOf instead.
Then there is a bunch of talk of snapshots. This all leaves me scratching my head wondering how I create a reusable view that can be injected with state. Any good examples, explanations, or other help out there?Guy Bieber
08/17/2020, 8:47 PMGuy Bieber
08/17/2020, 9:13 PMGuy Bieber
08/17/2020, 9:13 PMGuy Bieber
08/17/2020, 9:15 PMGuy Bieber
08/17/2020, 9:15 PMVinay Gaba
08/17/2020, 9:16 PMGuy Bieber
08/17/2020, 9:16 PMVinay Gaba
08/17/2020, 9:19 PMGuy Bieber
08/17/2020, 9:20 PMGuy Bieber
08/17/2020, 9:20 PMGuy Bieber
08/17/2020, 9:21 PMGuy Bieber
08/17/2020, 9:24 PMGuy Bieber
08/17/2020, 9:28 PM@Composable
@OptIn(
ExperimentalFocus::class,
ExperimentalKeyInput::class
)
private fun FocusableText(text: MutableState<String>) {
var color by state { Color.Black }
val focusRequester = FocusRequester()
Text(
modifier = Modifier
.focusRequester(focusRequester)
.focusObserver { color = if (it.isFocused) Color.Green else Color.Black }
.focus()
.tapGestureFilter { focusRequester.requestFocus() }
.keyInputFilter { it.value?.let { text.value += it; true } ?: false },
text = text.value,
color = color
)
}
It looks like you have to declare your whole model as mutable state and the primitive level.Guy Bieber
08/17/2020, 9:30 PMVinay Gaba
08/17/2020, 9:32 PMAppContent
accepts the navigationViewModel
but all the child composables have no information about the view model. They just receive callbacks. This way, you can continue making state changes using the view model, without your composable knowing anything about the view model itself.
2. Your second option is similar to the first one with a slight difference. Assuming you are storing your view state in LiveData/Flow/Rx objects, you can convert them to compose primitives using the observeAsState
extension function. That way, you can pass around state objects in compose land while continuing to use your existing setup.Guy Bieber
08/17/2020, 9:41 PMGuy Bieber
08/17/2020, 9:42 PMVinay Gaba
08/17/2020, 9:43 PMVinay Gaba
08/17/2020, 9:44 PM@Model
class? Can you post some code of what that “action” looks like.Guy Bieber
08/17/2020, 10:07 PMfun flashAction() {
// if the control is not disabled make the request
if (!appModel.homeView.flashControl.state.disabled && !appModel.homeView.flashControl.state.transition ) {
appModel.homeView.flashControl.startTransition()
var msg = UnitType.Flash()
msg.value = !appModel.session.unitType.flash.value
communication.tx(msg)
}
}
Guy Bieber
08/17/2020, 10:08 PMGuy Bieber
08/17/2020, 10:08 PMfun flashRxAction (msg : UnitType.Flash, connection : Connections) {
// update the application state
appModel.session.unitType.flash = msg
// update home view
appModel.homeView.flashControl.active(appModel.session.unitType.flash.value)
appModel.homeView.flashControl.stopTransition()
}
Guy Bieber
08/17/2020, 10:11 PMGuy Bieber
08/17/2020, 10:13 PM//@Model
data class ControlState (
var active : MutableState<Boolean> = false ,
var disabled : Boolean = true,
var transition : Boolean = false
)
The control changes its color based on active, disabled, and transition state.Guy Bieber
08/17/2020, 10:14 PMGuy Bieber
08/17/2020, 10:14 PMVinay Gaba
08/17/2020, 10:25 PMI just need a simple way to inject state into a view.
Ambients are one way to do this although my personal preference is to pass the state objects all the way through to the composables instead of injecting. I expect this area to evolve as we get closer to the 1.0 release. Still early days until we figure out what feels great.Guy Bieber
08/17/2020, 10:29 PMGuy Bieber
08/17/2020, 10:30 PMGuy Bieber
08/17/2020, 10:30 PMGuy Bieber
08/17/2020, 10:38 PMGuy Bieber
08/17/2020, 10:55 PMBefore:
@Model
data class ControlState (
var active : Boolean = false ,
var disabled : Boolean = true,
var transition : Boolean = false
)
After:
class ControlState (
active : Boolean = false,
disabled : Boolean = true,
transition : Boolean = false
) {
var active by mutableStateOf(active)
var disabled by mutableStateOf(disabled)
var transition by mutableStateOf(transition)
}
Guy Bieber
08/17/2020, 11:00 PM