Skip to content

Commit f085953

Browse files
Migrate wheel pickers to KMP Wheel Picker
1 parent eade667 commit f085953

File tree

11 files changed

+93
-599
lines changed

11 files changed

+93
-599
lines changed

core/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ android { namespace = "com.patrykandpatryk.liftapp.core" }
77
dependencies {
88
api(project(":ui"))
99
implementation(project(":navigation"))
10+
implementation(libs.kmp.wheel.picker)
1011
implementation(libs.opto.domain)
1112
}

core/src/main/kotlin/com/patrykandpatryk/liftapp/core/ui/wheel/DurationPicker.kt

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,26 @@ import androidx.compose.ui.hapticfeedback.HapticFeedbackType
2323
import androidx.compose.ui.platform.LocalHapticFeedback
2424
import androidx.compose.ui.res.stringResource
2525
import androidx.compose.ui.unit.dp
26+
import androidx.compose.ui.unit.times
2627
import com.patrykandpatrick.liftapp.ui.component.LiftAppHorizontalDivider
2728
import com.patrykandpatrick.liftapp.ui.preview.LightAndDarkThemePreview
2829
import com.patrykandpatrick.liftapp.ui.theme.LiftAppTheme
2930
import com.patrykandpatrick.liftapp.ui.theme.colorScheme
3031
import com.patrykandpatryk.liftapp.core.R
32+
import com.swmansion.kmpwheelpicker.WheelPicker
33+
import com.swmansion.kmpwheelpicker.rememberWheelPickerState
34+
import kotlin.math.round
3135
import kotlin.time.Duration
3236
import kotlin.time.Duration.Companion.hours
3337
import kotlin.time.Duration.Companion.minutes
3438
import kotlin.time.Duration.Companion.seconds
3539
import kotlinx.coroutines.NonCancellable
3640
import kotlinx.coroutines.launch
3741

42+
private val windowHeight = 44.dp
43+
44+
private const val BUFFER_SIZE = 2
45+
3846
@Composable
3947
fun 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(

core/src/main/kotlin/com/patrykandpatryk/liftapp/core/ui/wheel/ScrollSyncEffect.kt

Lines changed: 0 additions & 63 deletions
This file was deleted.

0 commit comments

Comments
 (0)