@@ -23,18 +23,26 @@ import androidx.compose.ui.hapticfeedback.HapticFeedbackType
2323import androidx.compose.ui.platform.LocalHapticFeedback
2424import androidx.compose.ui.res.stringResource
2525import androidx.compose.ui.unit.dp
26+ import androidx.compose.ui.unit.times
2627import com.patrykandpatrick.liftapp.ui.component.LiftAppHorizontalDivider
2728import com.patrykandpatrick.liftapp.ui.preview.LightAndDarkThemePreview
2829import com.patrykandpatrick.liftapp.ui.theme.LiftAppTheme
2930import com.patrykandpatrick.liftapp.ui.theme.colorScheme
3031import com.patrykandpatryk.liftapp.core.R
32+ import com.swmansion.kmpwheelpicker.WheelPicker
33+ import com.swmansion.kmpwheelpicker.rememberWheelPickerState
34+ import kotlin.math.round
3135import kotlin.time.Duration
3236import kotlin.time.Duration.Companion.hours
3337import kotlin.time.Duration.Companion.minutes
3438import kotlin.time.Duration.Companion.seconds
3539import kotlinx.coroutines.NonCancellable
3640import kotlinx.coroutines.launch
3741
42+ private val windowHeight = 44 .dp
43+
44+ private const val BUFFER_SIZE = 2
45+
3846@Composable
3947fun DurationPicker (
4048 duration : Duration ,
@@ -44,52 +52,45 @@ fun DurationPicker(
4452) {
4553 val hapticFeedback = LocalHapticFeedback .current
4654 val timeFormat = remember { DecimalFormat (" 00" ) }
47- val allHours = remember { List (60 ) { it } }
48- val allMinutes = remember { List (60 ) { it } }
49- val allSeconds = remember { List (60 ) { it } }
5055 val (hours, minutes, seconds) =
5156 duration.toComponents { _, hours, minutes, seconds, _ -> Triple (hours, minutes, seconds) }
52- val hourState = rememberWheelPickerState(initialSelectedIndex = hours)
53- val minuteState = rememberWheelPickerState(initialSelectedIndex = minutes)
54- val secondState = rememberWheelPickerState(initialSelectedIndex = seconds)
57+ val hourState = rememberWheelPickerState(itemCount = 60 , initialIndex = hours)
58+ val minuteState = rememberWheelPickerState(itemCount = 60 , initialIndex = minutes)
59+ val secondState = rememberWheelPickerState(itemCount = 60 , initialIndex = seconds)
5560 val onTimeChangeState = rememberUpdatedState(onDurationChange)
5661
5762 LaunchedEffect (hours, minutes, seconds) {
58- if (hours != hourState.targetItem)
63+ if (hours != hourState.index) {
5964 launch(NonCancellable ) { hourState.animateScrollTo(hours) }
60- if (minutes != minuteState.targetItem)
65+ }
66+ if (minutes != minuteState.index) {
6167 launch(NonCancellable ) { minuteState.animateScrollTo(minutes) }
62- if (seconds != secondState.targetItem)
68+ }
69+ if (seconds != secondState.index) {
6370 launch(NonCancellable ) { secondState.animateScrollTo(seconds) }
71+ }
6472 }
6573
66- LaunchedEffect (hourState.currentItem, minuteState.currentItem, secondState.currentItem ) {
74+ LaunchedEffect (round( hourState.value), round( minuteState.value), round( secondState.value) ) {
6775 hapticFeedback.performHapticFeedback(HapticFeedbackType .LongPress )
6876 }
6977
70- LaunchedEffect (hourState.targetItem, minuteState.targetItem, secondState.targetItem) {
71- val newDuration =
72- calculateDuration(
73- hour = allHours[hourState.targetItem],
74- minute = allMinutes[minuteState.targetItem],
75- second = allSeconds[secondState.targetItem],
76- )
78+ LaunchedEffect (hourState.index, minuteState.index, secondState.index) {
79+ val newDuration = calculateDuration(hourState.index, minuteState.index, secondState.index)
7780 if (newDuration != duration) onTimeChangeState.value(newDuration)
7881 }
7982
80- Box (modifier = modifier) {
81- WheelPickerDefaults .Highlight (
82- modifier = Modifier .fillMaxWidth().height(44 .dp).align(Alignment .Center )
83- )
83+ Box (modifier.height((2 * BUFFER_SIZE - 1 ) * windowHeight)) {
84+ WheelPickerWindow (Modifier .fillMaxWidth().height(windowHeight).align(Alignment .Center ))
8485
8586 Row (
8687 horizontalArrangement = Arrangement .Center ,
8788 verticalAlignment = Alignment .CenterVertically ,
8889 modifier = Modifier .fillMaxWidth(),
8990 ) {
9091 if (includeHours) {
91- WheelPicker (state = hourState, itemExtent = 1 , highlight = null ) {
92- allHours.forEach { value -> WheelPickerItem (timeFormat.format(value)) }
92+ WheelPicker (state = hourState, bufferSize = BUFFER_SIZE ) { index ->
93+ WheelPickerItem (timeFormat.format(index), index, hourState.value, BUFFER_SIZE )
9394 }
9495
9596 Text (
@@ -100,8 +101,8 @@ fun DurationPicker(
100101 )
101102 }
102103
103- WheelPicker (state = minuteState, itemExtent = 1 , highlight = null ) {
104- allMinutes.forEach { value -> WheelPickerItem (timeFormat.format(value)) }
104+ WheelPicker (state = minuteState, bufferSize = BUFFER_SIZE ) { index ->
105+ WheelPickerItem (timeFormat.format(index), index, minuteState.value, BUFFER_SIZE )
105106 }
106107
107108 Text (
@@ -111,8 +112,8 @@ fun DurationPicker(
111112 modifier = Modifier .offset(y = (- 1 ).dp),
112113 )
113114
114- WheelPicker (state = secondState, itemExtent = 1 , highlight = null ) {
115- allSeconds.forEach { index -> WheelPickerItem (timeFormat.format(index)) }
115+ WheelPicker (state = secondState, bufferSize = BUFFER_SIZE ) { index ->
116+ WheelPickerItem (timeFormat.format(index), index, secondState.value, BUFFER_SIZE )
116117 }
117118
118119 Text (
0 commit comments