Skip to content

Commit

Permalink
🎨 [#29] Merge Branch #11
Browse files Browse the repository at this point in the history
  • Loading branch information
Lee-Jun-Young committed Jan 23, 2024
1 parent 8681c1c commit 30bf11f
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,26 @@ import kotlinx.coroutines.flow.map
@Composable
fun ScrollableSelector(
modifier: Modifier,
valueList: List<Int>,
value: Int,
valueList: List<String>,
value: String,
limit: Int = 3,
suffix: @Composable (() -> Unit) = {},
onValueChanged: (Int) -> Unit,
onValueChanged: (String) -> Unit,
isYear: Boolean = false,
is24Hour: Boolean = true,
arrangement: Dp = 8.dp,
highlightFontColor: Color = Color.Black,
fontColor: Color = Color.DarkGray,
highlightTextStyle: TextStyle = MaterialTheme.typography.titleMedium,
textStyle: TextStyle = MaterialTheme.typography.titleSmall,
) {

require(limit % 2 != 0) { "limit Must be Odd."}
require(limit % 2 != 0) { "limit Must be Odd." }
Row(
modifier = modifier,
verticalAlignment = Alignment.CenterVertically
) {
if (isYear) {
if (isYear || is24Hour.not()) {
FiniteLazyColumn(
modifier = modifier,
valueList = valueList,
Expand All @@ -71,29 +72,32 @@ fun ScrollableSelector(
@Composable
fun FiniteLazyColumn(
modifier: Modifier = Modifier,
valueList: List<Int>,
value: Int,
valueList: List<String>,
value: String,
limit: Int,
arrangement: Dp = 8.dp,
highlightFontColor: Color = Color.Black,
fontColor: Color = Color.DarkGray,
highlightTextStyle: TextStyle = MaterialTheme.typography.titleMedium,
textStyle: TextStyle = MaterialTheme.typography.titleSmall,
onValueChanged: (Int) -> Unit,
onValueChanged: (String) -> Unit,
) {

val yearValueList = valueList.toMutableList()

yearValueList.add(yearValueList.lastIndex + 1, 0)
yearValueList.add(yearValueList.lastIndex + 1, 0)
yearValueList.add(0, 0)
yearValueList.add(0, 0)
val halfLimit = limit / 2

repeat(halfLimit) {
yearValueList.add(0, "0")
yearValueList.add(yearValueList.lastIndex + 1, "0")
}

val unSelectLineHeight = (textStyle.lineHeight * (limit - 1))
val lineHeight = rememberUpdatedState(newValue = unSelectLineHeight.value + highlightTextStyle.lineHeight.value + (arrangement.value * (limit - 2)))
val lineHeight =
rememberUpdatedState(newValue = unSelectLineHeight.value + highlightTextStyle.lineHeight.value + (arrangement.value * (halfLimit)))
val listState =
rememberLazyListState(initialFirstVisibleItemIndex = (yearValueList.indexOf(value) - 2))
val centerIndex = remember { mutableStateOf((listState.firstVisibleItemIndex + 2)) }
rememberLazyListState(initialFirstVisibleItemIndex = (yearValueList.indexOf(value) - halfLimit))
val centerIndex = remember { mutableStateOf((listState.firstVisibleItemIndex + halfLimit)) }
val centerItem = remember { mutableStateOf(yearValueList[centerIndex.value]) }
val flingBehavior = rememberSnapFlingBehavior(lazyListState = listState)

Expand All @@ -108,7 +112,7 @@ fun FiniteLazyColumn(
val item = yearValueList[index]

Row {
if (item != 0) {
if (item != "0") {
if (item == centerItem.value) {
Text(text = "$item", style = highlightTextStyle, color = highlightFontColor)
} else {
Expand All @@ -124,7 +128,7 @@ fun FiniteLazyColumn(
// call center value
LaunchedEffect(listState) {
snapshotFlow { listState.firstVisibleItemIndex }.distinctUntilChanged().map {
(it % yearValueList.size) + limit / 2
(it % yearValueList.size) + halfLimit
}.collectLatest { index ->
centerIndex.value = index % yearValueList.size
centerItem.value = yearValueList[centerIndex.value]
Expand All @@ -137,20 +141,21 @@ fun FiniteLazyColumn(
@Composable
internal fun InfiniteLazyColumn(
modifier: Modifier = Modifier,
valueList: List<Int>,
value: Int,
valueList: List<String>,
value: String,
limit: Int,
arrangement: Dp = 8.dp,
onValueChanged: (Int) -> Unit,
onValueChanged: (String) -> Unit,
highlightFontColor: Color = Color.Black,
fontColor: Color = Color.DarkGray,
highlightTextStyle: TextStyle = MaterialTheme.typography.titleMedium,
textStyle: TextStyle = MaterialTheme.typography.titleSmall,
) {
val unSelectLineHeight = (textStyle.lineHeight * (limit - 1))
val lineHeight = rememberUpdatedState(newValue = unSelectLineHeight.value + highlightTextStyle.lineHeight.value + (arrangement.value * (limit - 2)))
val lineHeight =
rememberUpdatedState(newValue = unSelectLineHeight.value + highlightTextStyle.lineHeight.value + (arrangement.value * (limit - 2)))
val listState = rememberLazyListState(
initialFirstVisibleItemIndex = (value + valueList.size - (limit / 2) - 1) % valueList.size
initialFirstVisibleItemIndex = (value.toInt() + valueList.size - (limit / 2) - 1) % valueList.size
)
val centerIndex =
remember { mutableStateOf((listState.firstVisibleItemIndex + limit / 2) % valueList.size) }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
package com.composepicker.picker.timepicker

import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.composepicker.picker.component.ScrollableSelector

@Suppress("UNUSED")
Expand All @@ -13,7 +21,12 @@ fun ProgTimePicker(
timePickerState: ProgTimePickerState,
hourSuffix: @Composable () -> Unit = {},
minuteSuffix: @Composable () -> Unit = {},
onTimeChanged: (hour: String, minute: String, meridiem: String) -> Unit
onTimeChanged: (hour: String, minute: String, meridiem: String) -> Unit,
arrangement: Dp = 8.dp,
highlightFontColor: Color = Color.Black,
fontColor: Color = Color.DarkGray,
highlightTextStyle: TextStyle = MaterialTheme.typography.titleMedium,
textStyle: TextStyle = MaterialTheme.typography.titleSmall
) {

Row(modifier = modifier) {
Expand All @@ -22,7 +35,13 @@ fun ProgTimePicker(
valueList = timePickerState.hourList,
value = timePickerState.hour,
suffix = hourSuffix,
onValueChanged = { onTimeChanged(it, timePickerState.minute, timePickerState.meridiem) })
onValueChanged = {
onTimeChanged(
it,
timePickerState.minute,
timePickerState.meridiem
)
})

ScrollableSelector(
modifier = modifier,
Expand All @@ -37,7 +56,13 @@ fun ProgTimePicker(
valueList = timePickerState.meridiemList,
value = timePickerState.meridiem,
suffix = minuteSuffix,
onValueChanged = { onTimeChanged(timePickerState.hour, timePickerState.minute, it) },
onValueChanged = {
onTimeChanged(
timePickerState.hour,
timePickerState.minute,
it
)
},
is24Hour = false
)
}
Expand All @@ -47,8 +72,14 @@ fun ProgTimePicker(
@Preview
@Composable
fun PreviewProgTimePicker() {
ProgTimePicker(
timePickerState = ProgTimePickerState(1, 1, is24Hour = true, timeGap = TimeGap.FIVE),
onTimeChanged = { a, b, c -> }
)
Surface(
modifier = Modifier.padding(12.dp),
color = Color.Gray,
shape = RoundedCornerShape(1)
) {
ProgTimePicker(
timePickerState = ProgTimePickerState(1, 30, is24Hour = false, timeGap = TimeGap.ONE_THIRD),
onTimeChanged = { a, b, c -> }
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package com.composepicker.picker.timepicker
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.rememberSaveable
Expand All @@ -13,18 +12,19 @@ import androidx.compose.runtime.setValue
class ProgTimePickerState(
initialHour: Int,
initialMinute: Int,
initialMeridiem: String = "AM",
val is24Hour: Boolean = false,
val timeGap: TimeGap = TimeGap.ONE
) {
init {
require(initialHour in 0..23) { "initialHour should in [0..23] range" }
require(initialMinute in 0..59) { "initialMinute should be in [0..59] range" }
require(initialMinute % timeGap.interval != 0) { "initialMinute should be matched with timeGap interval."}
require(initialMinute % timeGap.interval == 0) { "initialMinute should be matched with timeGap interval." }
}

var hour by mutableStateOf(initialHour.toString())
var minute by mutableStateOf(initialMinute.toString())
var meridiem by mutableStateOf("AM")
var meridiem by mutableStateOf(initialMeridiem)

val hourList: List<String> =
if (is24Hour) (0..23).map { it.toString() } else (1..12).map { it.toString() }
Expand All @@ -48,8 +48,9 @@ class ProgTimePickerState(
ProgTimePickerState(
initialHour = value[0] as Int,
initialMinute = value[1] as Int,
is24Hour = value[2] as Boolean,
timeGap = value[3] as TimeGap,
initialMeridiem = value[2] as String,
is24Hour = value[3] as Boolean,
timeGap = value[4] as TimeGap,
)
}
)
Expand All @@ -62,12 +63,14 @@ class ProgTimePickerState(
fun rememberProgTimePickerState(
initialHour: Int = 0,
initialMinute: Int = 0,
initialMeridiem: String = "AM",
is24Hour: Boolean = false,
timeGap: TimeGap = TimeGap.ONE
): ProgTimePickerState = rememberSaveable(saver = ProgTimePickerState.Saver()) {
ProgTimePickerState(
initialHour,
initialMinute,
initialMeridiem,
is24Hour,
timeGap
)
Expand Down

0 comments on commit 30bf11f

Please sign in to comment.