Lukasz Kalnik
08/09/2022, 1:03 PMvar thresholdProgress: Float by rememberSaveable(uiState.thresholdProgress) {
mutableStateOf(uiState.thresholdProgress)
}
Slider(
value = thresholdProgress,
onValueChange = {
thresholdProgress = it
viewModel.onThresholdProgressChanged(it)
},
)
fun onThresholdProgressChanged(progress: Float) {
val progressStep = (progress * 100).roundToInt()
val lux = if (progressStep <= 50) {
progressStep
} else {
50 + (progressStep - 50) * 5
}
_uiState.update { it.copy(lux = lux) }
}
uiState.lux
is used for continuously updating the lux number in the UI as user drags the slider.onThresholdProgressChanged()
then the slider becomes responsive again.
Should I move the calculation to another dispatcher? Is it blocking the main thread?Filip Wiesner
08/09/2022, 1:09 PMuiState.lux
in UI and update the thresholdProgress
MutableState?Zoltan Demant
08/09/2022, 1:09 PMLukasz Kalnik
08/09/2022, 1:09 PMuiState.lux
I only update the LUX value in the text fieldthresholdProgress
is remembered directly in the composableonValueChanged
callback is not throttled in any wayonThresholdProgressChanged()
Text(
text = stringResource(id = R.string.light_sensor_settings_threshold_lux, uiState.lux),
style = BegaTheme.typography.captionDynamic,
)
Zoltan Demant
08/09/2022, 1:14 PMLukasz Kalnik
08/09/2022, 1:14 PMModalBottomSheetLayout
sheetContent
is just a simple Column
with a few Rows containing the Slider and the Text and Icon elementsZoltan Demant
08/09/2022, 1:16 PMLukasz Kalnik
08/09/2022, 1:16 PMZoltan Demant
08/09/2022, 1:16 PMLukasz Kalnik
08/09/2022, 1:17 PMuiState.lux
from the callbackonThresholdProgressChanged()
uiState
updates somehowZoltan Demant
08/09/2022, 1:19 PMrememberSaveable(uiState.thresholdProgress)
I think youre creating a new mutableState everytime the progress changesLukasz Kalnik
08/09/2022, 1:20 PMthresholdProgress
in the ViewModel is only updated when I load the data from API when creating the bottom sheet for the first time.
The value in the ViewModel is not updated while dragging the slider.Zoltan Demant
08/09/2022, 1:23 PMLukasz Kalnik
08/09/2022, 1:24 PMZoltan Demant
08/09/2022, 1:24 PMLukasz Kalnik
08/09/2022, 1:24 PMZoltan Demant
08/09/2022, 1:25 PMLukasz Kalnik
08/09/2022, 1:39 PMZoltan Demant
08/09/2022, 1:44 PMLukasz Kalnik
08/09/2022, 1:45 PMZoltan Demant
08/09/2022, 2:01 PMLukasz Kalnik
08/09/2022, 2:08 PMRick Regan
08/09/2022, 2:11 PMvalueRange = 0f..100f
and steps = 99
. (Endpoints would be 0, 100 which I think matches what you have now.) If you use the Material3 version of slider you’ll get fewer callbacks (only on the “integer” ticks...I say “integer” because they’re floats and may be ever so slightly off the integer marks).Lukasz Kalnik
08/09/2022, 2:14 PMRick Regan
08/09/2022, 2:27 PMLukasz Kalnik
08/09/2022, 2:30 PMuiState.lux
(which only influences the Text
displaying the LUX value) then the Slider moves super fluidly.ModalBottomSheetLayout
?Zoltan Demant
08/09/2022, 2:33 PMSideEffect {
Log.d("TAG", "Recomp")
}
Lukasz Kalnik
08/09/2022, 2:36 PMZoltan Demant
08/09/2022, 2:39 PMLukasz Kalnik
08/09/2022, 2:39 PMSlider
Zoltan Demant
08/09/2022, 2:57 PMLukasz Kalnik
08/09/2022, 3:03 PMSystemFragment
where the composables are inflated and the state from viewmodels gets collected
SystemScreen
which is a ModalBottomSheetLayout
where the sheetContent
is the SensorSettingsSheet
containing the `Slider`; the `SystemScreen`'s content is the screen visible in the background
SensorSettingsSheet
which is the actual composable where the Slider
isZoltan Demant
08/09/2022, 3:10 PMLukasz Kalnik
08/09/2022, 3:12 PMuiState
value actually changes get recomposed...uiState
and only recompose what's needed?Zoltan Demant
08/09/2022, 3:15 PMLukasz Kalnik
08/09/2022, 3:18 PM@Immutable
and the slider is still as laggy as it wasZoltan Demant
08/09/2022, 3:18 PMLukasz Kalnik
08/09/2022, 3:19 PMZoltan Demant
08/09/2022, 3:22 PMLukasz Kalnik
08/09/2022, 3:23 PMStylianos Gakis
08/09/2022, 3:56 PMZoltan Demant
08/09/2022, 3:58 PMuiState.collectAsState()
like you currently are, but replace 'by' with '=' so that you get a State<UiState>. Pass it to the inner composables, like I mentioned with viewmodel, but only read (state.value) its value where youre also using it.
2. Pass uiState (the stateflow) down the composables instead, and collectAsState() where you also read the value 🙂Lukasz Kalnik
08/09/2022, 4:00 PMmutableStateOf(MyUiState(...))
.
BTW if you don't use viewmodels, what do you use? Do you just keep the whole state in the composable itself?Zoltan Demant
08/09/2022, 4:04 PMLukasz Kalnik
08/09/2022, 4:05 PMby
with =
in collectAsState()
and only reading the value
inside the actual composable that's interested in it.ModalBottomSheetLayout
. That might have caused too many calculations, even though in the end the state of the bottom sheet didn't influence the state of the screen visible in the background.Stylianos Gakis
08/09/2022, 4:13 PMLukasz Kalnik
08/09/2022, 4:19 PMStylianos Gakis
08/09/2022, 4:22 PMLukasz Kalnik
08/09/2022, 4:23 PMStylianos Gakis
08/09/2022, 4:28 PMLukasz Kalnik
08/09/2022, 4:30 PMmyanmarking
08/10/2022, 8:27 AMLukasz Kalnik
08/10/2022, 9:00 AM