Se7eN
01/07/2021, 1:17 PM@Composable
fun Main() {
val state = remember { PaletteState(...) }
Scaffold(
topBar = { TopBar(onSave = { viewModel.save(state.toPalette()) } }
) {
ColorWheel(state)
}
}
@Composable
fun ColorWheel(state: PaletteState) {
val colorWheel = rememeber { ColorWheel(...) }
state.colors = colorWheel.getColors()
Content(colorWheel)
}
I have a state
that needs to be updated by a child composable. Is this the right way to do it?sindrenm
01/07/2021, 1:23 PMonColorSelected: (Color) -> Unit
or something) to the child.Lukas Sztefek
01/07/2021, 1:23 PMfun ColorWheel(onPalletteChanged: (PaletteState) -> Unit) {
Se7eN
01/07/2021, 1:26 PMonPaletteChanged()
or state.colors = colorWheel.getColors()
without a callback doesn't seem rightLukas Sztefek
01/07/2021, 1:38 PMSe7eN
01/07/2021, 1:39 PMLukas Sztefek
01/07/2021, 1:47 PMI don't really have a way to get the initial colors of the color wheel
but also The child is responsible for initializing the palette
. This statements are going against each other aren’t they? Colors != palette?Se7eN
01/07/2021, 1:52 PMinit { }
of the class that is responsible for initalizing the palette?jim
01/07/2021, 2:08 PMColorWheel
should not be the one who controls the initial colors; if the parent needs to maintain the current color, then they should own that state, including owning the initial color.fun ColorWheel(palette: List<Color>, currentColor: Color, onColorSelected: (Color) -> Unit) {
...
}
Or:
fun ColorWheel(palette: List<Color>, onPaletteSelected: (List<Color>) -> Unit) {
...
}
Or whatever it is exactly your widget is allowing you to select. The key is that the child is just rendering the state the parent passes down, and then informing the parent when the child thinks that state should be changed. The parent owns the data.
When first getting started with Compose, it's often useful to ask yourself "How would I do this if I were only permitted to use immutable data structures", as that will often lead you to the proper data flow.Se7eN
01/07/2021, 2:20 PMclass ColorWheel(hueDistance, numColors, ...) {
// Initialize the list of colors using hueDistance and numColors and a few other parameters
}
That's why I can't pass any initial color list to the color wheel. You think I should do the initial palette calculation outside the ColorWheel
?Lukas Sztefek
01/07/2021, 2:21 PMclass PaletteState(
var colors: List<Color>
)
@Composable
fun Main() {
val paletteState = remember { PaletteState(listOf(Color.Red, Color.Blue)) }
ColorWheel(
currentColors = paletteState.colors,
onColorsChanged = { paletteState.colors = it }
)
}
@Composable
fun ColorWheel(currentColors: List<Color>, onColorsChanged: (List<Color>) -> Unit) {
Content(
currentColors = currentColors,
onDrag = { selectedColors -> onColorsChanged(selectedColors) }
)
}
Se7eN
01/07/2021, 2:26 PMLukas Sztefek
01/07/2021, 2:33 PMjim
01/07/2021, 2:33 PMColorWheel
, perhaps into something like PaletteState
or ColorWheelState
, but keep these things immutable and just re-create them any time one of the parameters changes. That will keep your data flow correct.Se7eN
01/07/2021, 2:35 PM