Document NumberPicker Composable and it's util classes, functions
This commit is contained in:
parent
ef15aca31f
commit
db9c62884f
9 changed files with 151 additions and 29 deletions
|
|
@ -31,7 +31,7 @@ fun NumberPickerScreen() {
|
|||
var selected by remember { mutableStateOf(0) }
|
||||
NumberPicker(
|
||||
modifier = Modifier.defaultMinSize(minWidth = 200.dp),
|
||||
onSelectedChange = {
|
||||
onSelectedValueChange = {
|
||||
selected = it
|
||||
},
|
||||
textStyle = MaterialTheme.typography.h5,
|
||||
|
|
@ -44,7 +44,7 @@ fun NumberPickerScreen() {
|
|||
NumberPicker(
|
||||
config = NumberPickerConfig.configMinutePicker,
|
||||
selectedValue = selected,
|
||||
onSelectedChange = { selected = it },
|
||||
onSelectedValueChange = { selected = it },
|
||||
roundAround = false,
|
||||
textStyle = MaterialTheme.typography.h5
|
||||
)
|
||||
|
|
@ -55,7 +55,7 @@ fun NumberPickerScreen() {
|
|||
NumberPicker(
|
||||
config = NumberPickerConfig.configMinutePicker,
|
||||
selectedValue = selected,
|
||||
onSelectedChange = { selected = it },
|
||||
onSelectedValueChange = { selected = it },
|
||||
timePicker = { LinedInnerTextPicker(modifier = Modifier.defaultMinSize(minWidth = 200.dp)) }
|
||||
)
|
||||
}
|
||||
|
|
@ -66,7 +66,7 @@ fun NumberPickerScreen() {
|
|||
NumberPicker(
|
||||
config = NumberPickerConfig.configHourPicker24,
|
||||
selectedValue = selected,
|
||||
onSelectedChange = { selected = it }
|
||||
onSelectedValueChange = { selected = it }
|
||||
) {
|
||||
TextPicker(
|
||||
modifier = Modifier.defaultMinSize(minWidth = 200.dp),
|
||||
|
|
@ -88,7 +88,7 @@ fun NumberPickerScreen() {
|
|||
NumberPicker(
|
||||
config = NumberPickerConfig(maximum = 5, minimum = 1, skipInBetween = 1),
|
||||
selectedValue = selected,
|
||||
onSelectedChange = { selected = it }
|
||||
onSelectedValueChange = { selected = it }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -99,7 +99,7 @@ fun NumberPickerScreen() {
|
|||
NumberPicker(
|
||||
config = NumberPickerConfig(maximum = 5, minimum = 1, skipInBetween = 2),
|
||||
selectedValue = selected,
|
||||
onSelectedChange = { selected = it }
|
||||
onSelectedValueChange = { selected = it }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -110,7 +110,7 @@ fun NumberPickerScreen() {
|
|||
NumberPicker(
|
||||
config = NumberPickerConfig(maximum = 5, minimum = 1, skipInBetween = 1, reversedOrder = true),
|
||||
selectedValue = selected,
|
||||
onSelectedChange = { selected = it }
|
||||
onSelectedValueChange = { selected = it }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -122,7 +122,7 @@ fun NumberPickerScreen() {
|
|||
config = NumberPickerConfig(maximum = 5, minimum = 1, skipInBetween = 2, reversedOrder = true),
|
||||
selectedValue = selected,
|
||||
roundAround = false,
|
||||
onSelectedChange = { selected = it },
|
||||
onSelectedValueChange = { selected = it },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,12 +7,29 @@ import androidx.compose.ui.text.TextStyle
|
|||
import org.fknives.android.compose.picker.text.TextPickerState
|
||||
import org.fknives.android.compose.picker.text.util.TextPickerDefaults
|
||||
|
||||
/**
|
||||
* Configuration API around [TextPicker][org.fknives.android.compose.picker.text.TextPicker].
|
||||
*
|
||||
* Sets up inner StateManagement of [TextPicker][org.fknives.android.compose.picker.text.TextPicker] in a [NumberPickerScope]
|
||||
* then places it via [CustomInnerTextPicker].
|
||||
*
|
||||
* @param modifier [Modifier] of [TextPicker][org.fknives.android.compose.picker.text.TextPicker]
|
||||
* @param config Configuration of NumberPicker. Defines the Number Range that should be shown.
|
||||
* @param selectedValue The selected value, expected to be between [config]'s minimum and maximum.
|
||||
* @param onSelectedValueChange Notified when the Selected Value Changes.
|
||||
* @param onIndexDifferenceChanging Signals the animation changes, how much the current dragging is away from index of [selectedValue].
|
||||
* Negative values mean the index were decreased, Positive means it was increased.
|
||||
* **IMPORTANT! works with index-difference, not values (minimumValue = 0 index)**
|
||||
* @param textStyle TextStyle of [TextPicker][org.fknives.android.compose.picker.text.TextPicker]
|
||||
* @param roundAround roundAround of [TextPicker][org.fknives.android.compose.picker.text.TextPicker].
|
||||
* Should behave like a Wheel, or should be limited.
|
||||
*/
|
||||
@Composable
|
||||
fun NumberPicker(
|
||||
modifier: Modifier = Modifier,
|
||||
config: NumberPickerConfig,
|
||||
selectedValue: Int,
|
||||
onSelectedChange: (Int) -> Unit,
|
||||
onSelectedValueChange: (Int) -> Unit,
|
||||
onIndexDifferenceChanging: (Int) -> Unit = TextPickerDefaults.onIndexDifferenceChanging,
|
||||
textStyle: TextStyle = LocalTextStyle.current,
|
||||
roundAround: Boolean = TextPickerDefaults.roundAround,
|
||||
|
|
@ -20,7 +37,7 @@ fun NumberPicker(
|
|||
NumberPicker(
|
||||
config = config,
|
||||
selectedValue = selectedValue,
|
||||
onSelectedChange = onSelectedChange,
|
||||
onSelectedValueChange = onSelectedValueChange,
|
||||
onIndexDifferenceChanging = onIndexDifferenceChanging
|
||||
) {
|
||||
CustomInnerTextPicker(
|
||||
|
|
@ -31,11 +48,28 @@ fun NumberPicker(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration API around [TextPicker][org.fknives.android.compose.picker.text.TextPicker].
|
||||
*
|
||||
* Sets up inner StateManagement of [TextPicker][org.fknives.android.compose.picker.text.TextPicker] in a [NumberPickerScope]
|
||||
* then places it via [timePicker].
|
||||
*
|
||||
* @param config Configuration of NumberPicker. Defines the Number Range that should be shown.
|
||||
* @param selectedValue The selected value, expected to be between [config]'s minimum and maximum.
|
||||
* @param onSelectedValueChange Notified when the Selected Value Changes.
|
||||
* @param onIndexDifferenceChanging Signals the animation changes, how much the current dragging is away from index of [selectedValue].
|
||||
* Negative values mean the index were decreased, Positive means it was increased.
|
||||
* **IMPORTANT! works with index-difference, not values (minimumValue = 0 index)**
|
||||
* Should behave like a Wheel, or should be limited.
|
||||
* @param state TextPickerState of [TextPicker][org.fknives.android.compose.picker.text.TextPicker]
|
||||
* @param timePicker The Lambda placing the TimePicker. [NumberPickerScope] is provided with the configuration setup.
|
||||
* *Note: Check [StandardInnerTextPicker], [CustomInnerTextPicker], if you wish to customize.*
|
||||
*/
|
||||
@Composable
|
||||
fun NumberPicker(
|
||||
config: NumberPickerConfig,
|
||||
selectedValue: Int,
|
||||
onSelectedChange: (Int) -> Unit,
|
||||
onSelectedValueChange: (Int) -> Unit,
|
||||
onIndexDifferenceChanging: (Int) -> Unit = TextPickerDefaults.onIndexDifferenceChanging,
|
||||
state: TextPickerState = rememberNumberPickerState(selectedValue = selectedValue, config = config),
|
||||
timePicker: @Composable NumberPickerScope.() -> Unit = { StandardInnerTextPicker() }
|
||||
|
|
@ -46,7 +80,7 @@ fun NumberPicker(
|
|||
state = state,
|
||||
config = config,
|
||||
onIndexDifferenceChanging = onIndexDifferenceChanging,
|
||||
onSelectedChange = onSelectedChange
|
||||
onSelectedValueChange = onSelectedValueChange
|
||||
)
|
||||
|
||||
timePicker(numberPickerScope)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,38 @@ package org.fknives.android.compose.picker.number
|
|||
|
||||
import androidx.compose.runtime.Immutable
|
||||
|
||||
/**
|
||||
* Configuration of [NumberPicker]
|
||||
*
|
||||
* [minimum] The minimum value shown inside the [NumberPicker]. Minimum Value included in the List of Elements.
|
||||
* [maximum] The maximum value shown inside the [NumberPicker]. Maximum Value included in the List of Elements.
|
||||
* [reversedOrder] false, means goes from [minimum]..[maximum], true means [maximum]..[minimum]
|
||||
* [skipInBetween], number of elements skipped when going from one value to another.
|
||||
*
|
||||
* Example1:
|
||||
* minimum = 1, maximum = 3, reversedOrder = false, skipInBetween=0
|
||||
* =>
|
||||
* [1,2,3]
|
||||
* *Note: No skipping, no reverse, so all elements from 1 to 3*
|
||||
*
|
||||
* Example2:
|
||||
* minimum = 1, maximum = 3, reversedOrder = true, skipInBetween=0
|
||||
* =>
|
||||
* [3,2,1]
|
||||
* *Note: No skipping, reverse, so all elements from 3 to 1*
|
||||
*
|
||||
* Example3:
|
||||
* minimum = 1, maximum = 5, reversedOrder = false, skipInBetween=1
|
||||
* =>
|
||||
* [1,3,5]
|
||||
* *Note: Skipping 1 element, no reverse, so starting from 1. Then skipping 2, so 3. Then skipping 4 so 5.*
|
||||
*
|
||||
* Example4:
|
||||
* minimum = 1, maximum = 5, reversedOrder = true, skipInBetween=2
|
||||
* =>
|
||||
* [5,2]
|
||||
* *Note: Skipping 2 element, Reverse, so starting from 5. Then skipping 4 and 3, so 2. Next would be smaller than minimal so, that's it.*
|
||||
*/
|
||||
@Immutable
|
||||
data class NumberPickerConfig(
|
||||
val maximum: Int,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,36 @@ import androidx.compose.runtime.remember
|
|||
import org.fknives.android.compose.picker.text.util.TextPickerDefaults
|
||||
import org.fknives.android.compose.picker.text.TextPickerState
|
||||
|
||||
/**
|
||||
* Prepared parameters for [TextPicker][org.fknives.android.compose.picker.text.TextPicker].
|
||||
*
|
||||
* [state] The [TextPickerState] expected to be set to [TextPicker][org.fknives.android.compose.picker.text.TextPicker]
|
||||
*
|
||||
* [onIndexDifferenceChanging] The onIndexDifferenceChanging Listener expected to be set to
|
||||
* [TextPicker][org.fknives.android.compose.picker.text.TextPicker]
|
||||
*
|
||||
* [onSelectedIndexChange] The onSelectedIndexChange Listener expected to be set to
|
||||
* [TextPicker][org.fknives.android.compose.picker.text.TextPicker]
|
||||
*
|
||||
* [textForIndex] The IndexToNumberVlaue Converter expected to be set to [TextPicker][org.fknives.android.compose.picker.text.TextPicker]
|
||||
*
|
||||
* [selectedIndex] The selectedIndex expected to be set to [TextPicker][org.fknives.android.compose.picker.text.TextPicker]
|
||||
*
|
||||
* [itemCount] The selectedIndex expected to be set to [TextPicker][org.fknives.android.compose.picker.text.TextPicker]
|
||||
*/
|
||||
@Immutable
|
||||
interface NumberPickerScope {
|
||||
val state: TextPickerState
|
||||
val onIndexDifferenceChanging: (Int) -> Unit
|
||||
val onSelectedIndexChange: (Int) -> Unit
|
||||
val textForIndex: (Int) -> String
|
||||
val selectedIndex: Int get() = state.selected
|
||||
val itemCount: Int get() = state.itemCount
|
||||
}
|
||||
|
||||
/**
|
||||
* Data class implementation of [NumberPickerScope]
|
||||
*/
|
||||
@Immutable
|
||||
data class NumberPickerScopeImpl(
|
||||
override val state: TextPickerState,
|
||||
|
|
@ -17,11 +47,20 @@ data class NumberPickerScopeImpl(
|
|||
override val itemCount: Int get() = state.itemCount
|
||||
}
|
||||
|
||||
/**
|
||||
* Caching function, preparing the [NumberPickerScope] from simple parameters.
|
||||
*
|
||||
* @param state The [TextPickerState] expected to be set to [TextPicker][org.fknives.android.compose.picker.text.TextPicker]
|
||||
* @param config The NumberPickers config. Used to convert between TextPicker's Index and NumberPicker's values.
|
||||
* @param onSelectedValueChange NumberPicker's onSelectedValueChange Listener
|
||||
* @param onIndexDifferenceChanging NumberPicker's onIndexDifferenceChanging Listener
|
||||
* @param keys any additional keys, to signal changing of the scope cache.
|
||||
*/
|
||||
@Composable
|
||||
fun rememberNumberPickerScope(
|
||||
state: TextPickerState,
|
||||
config: NumberPickerConfig,
|
||||
onSelectedChange: (Int) -> Unit,
|
||||
onSelectedValueChange: (Int) -> Unit,
|
||||
onIndexDifferenceChanging: (Int) -> Unit = TextPickerDefaults.onIndexDifferenceChanging,
|
||||
vararg keys: Any?
|
||||
): NumberPickerScope {
|
||||
|
|
@ -34,18 +73,8 @@ fun rememberNumberPickerScope(
|
|||
textForIndex = { "${indexToNumber(it)}" },
|
||||
onIndexDifferenceChanging = onIndexDifferenceChanging,
|
||||
onSelectedIndexChange = {
|
||||
onSelectedChange(indexToNumber(it))
|
||||
onSelectedValueChange(indexToNumber(it))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Immutable
|
||||
interface NumberPickerScope {
|
||||
val state: TextPickerState
|
||||
val onIndexDifferenceChanging: (Int) -> Unit
|
||||
val onSelectedIndexChange: (Int) -> Unit
|
||||
val textForIndex: (Int) -> String
|
||||
val selectedIndex: Int get() = state.selected
|
||||
val itemCount: Int get() = state.itemCount
|
||||
}
|
||||
|
|
@ -8,6 +8,12 @@ import org.fknives.android.compose.picker.text.LinedTextPicker
|
|||
import org.fknives.android.compose.picker.text.TextPicker
|
||||
import org.fknives.android.compose.picker.text.util.TextPickerDefaults
|
||||
|
||||
/**
|
||||
* Custom [TextPicker] Creator for [NumberPicker], containing all styling [TextPicker].
|
||||
* Keeps all the default values of [TextPicker].
|
||||
*
|
||||
* For More Customization, Give your Custom TextPicker callback to [NumberPicker]
|
||||
*/
|
||||
@Composable
|
||||
fun NumberPickerScope.CustomInnerTextPicker(
|
||||
modifier: Modifier = Modifier,
|
||||
|
|
@ -27,6 +33,10 @@ fun NumberPickerScope.CustomInnerTextPicker(
|
|||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Default [TextPicker] Creator for [NumberPicker].
|
||||
* Keeps all the default values of [TextPicker].
|
||||
*/
|
||||
@Composable
|
||||
fun NumberPickerScope.StandardInnerTextPicker(modifier: Modifier = Modifier) {
|
||||
TextPicker(
|
||||
|
|
@ -40,6 +50,10 @@ fun NumberPickerScope.StandardInnerTextPicker(modifier: Modifier = Modifier) {
|
|||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Default [LinedTextPicker] Creator for [NumberPicker].
|
||||
* Keeps all the default values of [LinedTextPicker].
|
||||
*/
|
||||
@Composable
|
||||
fun NumberPickerScope.LinedInnerTextPicker(modifier: Modifier = Modifier) {
|
||||
LinedTextPicker(
|
||||
|
|
|
|||
|
|
@ -5,7 +5,11 @@ import androidx.compose.runtime.remember
|
|||
import org.fknives.android.compose.picker.text.TextPickerState
|
||||
import org.fknives.android.compose.picker.text.util.rememberTextPickerState
|
||||
|
||||
|
||||
/**
|
||||
* Caches function converting from TextPicker's Index to NumberPicker's NumberValues, defined by [config]
|
||||
*
|
||||
* Inverse of [valueToIndex]
|
||||
*/
|
||||
@Composable
|
||||
fun rememberNumberPickerIndexToNumber(config: NumberPickerConfig): (Int) -> Int =
|
||||
remember(config) {
|
||||
|
|
@ -20,6 +24,11 @@ fun rememberNumberPickerIndexToNumber(config: NumberPickerConfig): (Int) -> Int
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function converting from NumberPicker's NumberValues to TextPicker's Index, defined by [config].
|
||||
*
|
||||
* Inverse of [valueToIndex]
|
||||
*/
|
||||
private fun valueToIndex(config: NumberPickerConfig, value: Int): Int =
|
||||
if (config.reversedOrder) {
|
||||
(config.maximum - value) / (config.skipInBetween + 1)
|
||||
|
|
@ -27,6 +36,9 @@ private fun valueToIndex(config: NumberPickerConfig, value: Int): Int =
|
|||
(value - config.minimum) / (config.skipInBetween + 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Caches [TextPickerState] created from the NumberPicker's [config] and [selectedValue].
|
||||
*/
|
||||
@Composable
|
||||
fun rememberNumberPickerState(selectedValue: Int, config: NumberPickerConfig): TextPickerState {
|
||||
val selected = valueToIndex(value = selectedValue, config = config)
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ import org.fknives.android.compose.picker.text.util.rememberSafeTextForIndex
|
|||
* Setting this to False, means the first element has no elements above it, and the last element has no element below it.
|
||||
* @param onIndexDifferenceChanging Signals the animation changes, how much the current dragging is away from [selectedIndex].
|
||||
* Negative values mean the index were decreased, Positive means it was increased.
|
||||
* **IMPORTANT! works with index-difference, not index**
|
||||
* @param state Animation State for the TextPicker
|
||||
* @param animator Uses state to Animate the Composable elements. Handles continous drag, calculating fling and snapping to an index.
|
||||
* @param textPickerContent The actual Composables inside the TextPicker, by default it is the 4 Texts
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ fun TimePicker(
|
|||
val hourScope = rememberNumberPickerScope(
|
||||
state = hourState,
|
||||
config = hourConfig,
|
||||
onSelectedChange = {
|
||||
onSelectedValueChange = {
|
||||
onSelectedTimeChanged(selectedTime.copy(hour = it))
|
||||
}
|
||||
)
|
||||
|
|
@ -31,7 +31,7 @@ fun TimePicker(
|
|||
val minuteScope = rememberNumberPickerScope(
|
||||
state = minuteState,
|
||||
config = minuteConfig,
|
||||
onSelectedChange = {
|
||||
onSelectedValueChange = {
|
||||
onSelectedTimeChanged(selectedTime.copy(minute = it))
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ fun ClockTimePicker(
|
|||
changingIsAM = isAMResultByHourLapsCounter(lapsCounter, selectedTime.isAM)
|
||||
}
|
||||
},
|
||||
onSelectedChange = {
|
||||
onSelectedValueChange = {
|
||||
onSelectedTimeChanged(selectedTime.copy(hour = it, isAM = changingIsAM))
|
||||
},
|
||||
keys = arrayOf(changingHour, hoursLapCounterByIndex, changingIsAM)
|
||||
|
|
@ -66,7 +66,7 @@ fun ClockTimePicker(
|
|||
changingIsAM = isAMResultByHourLapsCounter(lapsCounter, selectedTime.isAM)
|
||||
changingHour = hourDifference
|
||||
},
|
||||
onSelectedChange = {
|
||||
onSelectedValueChange = {
|
||||
onSelectedTimeChanged(selectedTime.copy(hour = selectedTime.hour + changingHour, minute = it, isAM = changingIsAM))
|
||||
},
|
||||
keys = arrayOf(changingHour, hoursLapCounterByIndex, changingIsAM)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue