commandiron / wheelpickercompose Goto Github PK
View Code? Open in Web Editor NEWAdd Wheel Date - Time Picker in Android Jetpack Compose.
License: Apache License 2.0
Add Wheel Date - Time Picker in Android Jetpack Compose.
License: Apache License 2.0
Eg: For hour, scrolling should not stop after 12. Rather it should again loop to 1 and also switch AM to PM and vice versa.
For minutes, scrolling should loop after 59.
This is similar to how Xiaomi does it.
Shouldn't be much difficult to implement.
I cant give spesific text color to WheelTextPicker texts, when i give TextStyle(color = Color.White) to textStyle parameter, nothing happens and does not apply
Hello!
First of all, let me thank you for this super cool and handy library!
I was wondering if there is a way for onSnappedDateTime
to account for the intermediary values as the user scrolls.
This would be useful for example in the following scenario:
A user navigates to a page where they have the Wheel Picker. He scrolls the picker and as the wheel is still scrolling, he instantly saves the date and closes the page. The state would not still be updated since onSnappedDateTime
is called only when the picker is not scrolling. A good way to resolve this would be for onSnappedDateTime
to retrieve every value as the user scrolls so that even if he closes the page, the state would still be updated.
This is a nice project!
I am wondering if these components could support JetBrains/compose-multiplatform
Does this lib support for Java? If yes, can you provide Java sample code. Thanks.
Hi, is there any option for set Min and Max Date
From [https://github.com/chrisbanes/snapper]
Snapper is now deprecated, due to it's functionality being replaced by SnapFlingBehavior which is available in Jetpack Compose 1.3.0.
Hi @commandiron ,
Your library was amazing. However, I think it will be great if you add new param for change locale of the month text composable so that the library can support other language.
i cant use the date pickers for jalalian/solar date, if you put a parameter in pickers like transformBuilder @composable (Int)->Unit, it will be better, i can build my own text on picker, maybe i want to put persian month name ...
Running on 3 device
Samsung A51 Android 13,Samung Galaxy M22,Samsung Galaxy J4+
Got Error
Fatal Exception: java.lang.IllegalStateException: Offset is unspecified
at androidx.compose.ui.geometry.Offset.getX-impl(Offset.kt:67)
at androidx.compose.ui.graphics.Matrix.map-impl(Matrix.kt:86)
at androidx.compose.ui.platform.ViewLayer.mapBounds(ViewLayer.android.kt:365)
at androidx.compose.ui.node.NodeCoordinator.rectInParent$ui_release(NodeCoordinator.kt:976)
at androidx.compose.ui.node.NodeCoordinator.rectInParent$ui_release$default(NodeCoordinator.kt:954)
at androidx.compose.ui.node.NodeCoordinator.localBoundingBoxOf(NodeCoordinator.kt:845)
at androidx.compose.ui.layout.LayoutCoordinates.localBoundingBoxOf$default(LayoutCoordinates.kt:94)
at androidx.compose.ui.layout.LayoutCoordinatesKt.boundsInRoot(LayoutCoordinates.kt:128)
at androidx.compose.ui.node.SemanticsModifierNodeKt.touchBoundsInRoot(SemanticsModifierNode.kt:68)
at androidx.compose.ui.semantics.SemanticsNode.getTouchBoundsInRoot(SemanticsNode.kt:109)
at androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat_androidKt.getAllUncoveredSemanticsNodesToMap$findAllSemanticNodesRecursive(AndroidComposeViewAccessibilityDelegateCompat.android.kt:3077)
at androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat_androidKt.getAllUncoveredSemanticsNodesToMap$findAllSemanticNodesRecursive(AndroidComposeViewAccessibilityDelegateCompat.android.kt:3096)
at androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat_androidKt.getAllUncoveredSemanticsNodesToMap$findAllSemanticNodesRecursive(AndroidComposeViewAccessibilityDelegateCompat.android.kt:3096)
at androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat_androidKt.getAllUncoveredSemanticsNodesToMap$findAllSemanticNodesRecursive(AndroidComposeViewAccessibilityDelegateCompat.android.kt:3096)
at androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat_androidKt.getAllUncoveredSemanticsNodesToMap(AndroidComposeViewAccessibilityDelegateCompat.android.kt:3127)
at androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat.getCurrentSemanticsNodes(AndroidComposeViewAccessibilityDelegateCompat.android.kt:354)
at androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat.createEvent$ui_release(AndroidComposeViewAccessibilityDelegateCompat.android.kt:1406)
at androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat.sendEventForVirtualView(AndroidComposeViewAccessibilityDelegateCompat.android.kt:1358)
at androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat.sendEventForVirtualView$default(AndroidComposeViewAccessibilityDelegateCompat.android.kt:1348)
at androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat.sendSubtreeChangeAccessibilityEvents(AndroidComposeViewAccessibilityDelegateCompat.android.kt:2110)
at androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat.boundsUpdatesEventLoop(AndroidComposeViewAccessibilityDelegateCompat.android.kt:2028)
at androidx.compose.ui.platform.AndroidComposeView.boundsUpdatesEventLoop(AndroidComposeView.android.kt:1107)
at androidx.compose.ui.platform.WrappedComposition$setContent$1$1$1.invokeSuspend(Wrapper.android.kt:153)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at androidx.compose.ui.platform.AndroidUiDispatcher.performTrampolineDispatch(AndroidUiDispatcher.android.kt:81)
at androidx.compose.ui.platform.AndroidUiDispatcher.access$performTrampolineDispatch(AndroidUiDispatcher.android.kt:41)
at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.run(AndroidUiDispatcher.android.kt:57)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7094)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)
When you scroll to the last year in newest version (1.1.0) the app crashes.
Affected devices as far as I have tested: Samsung Galaxy S21 Ultra 5G (Android 13), Xiaomi Mi A2 Lite(Android 10)
Unaffected devices: TCL 20S
Was working fine before but now out of nowhere got this issue:
androidx.compose.ui.geometry.Offset.getX-impl Offset.java:28 androidx.compose.ui.graphics.Matrix.map-impl Matrix.java androidx.compose.ui.platform.RenderNodeLayer.mapBounds RenderNodeLayer.java androidx.compose.ui.node.NodeCoordinator.rectInParent$ui_release NodeCoordinator.java androidx.compose.ui.node.NodeCoordinator.rectInParent$ui_release$default NodeCoordinator.java androidx.compose.ui.node.NodeCoordinator.localBoundingBoxOf NodeCoordinator.java androidx.compose.ui.layout.LayoutCoordinates.localBoundingBoxOf$default LayoutCoordinates.java androidx.compose.ui.layout.LayoutCoordinatesKt.boundsInRoot LayoutCoordinatesKt.java androidx.compose.ui.node.SemanticsModifierNodeKt.touchBoundsInRoot SemanticsModifierNodeKt.java androidx.compose.ui.semantics.SemanticsNode.getTouchBoundsInRoot SemanticsNode.java androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat_androidKt.getAllUncoveredSemanticsNodesToMap$findAllSemanticNodesRecursive AndroidComposeViewAccessibilityDelegateCompat_androidKt.java androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat_androidKt.getAllUncoveredSemanticsNodesToMap$findAllSemanticNodesRecursive AndroidComposeViewAccessibilityDelegateCompat_androidKt.java androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat_androidKt.getAllUncoveredSemanticsNodesToMap$findAllSemanticNodesRecursive AndroidComposeViewAccessibilityDelegateCompat_androidKt.java androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat_androidKt.getAllUncoveredSemanticsNodesToMap$findAllSemanticNodesRecursive AndroidComposeViewAccessibilityDelegateCompat_androidKt.java androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat_androidKt.getAllUncoveredSemanticsNodesToMap$findAllSemanticNodesRecursive AndroidComposeViewAccessibilityDelegateCompat_androidKt.java androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat_androidKt.getAllUncoveredSemanticsNodesToMap AndroidComposeViewAccessibilityDelegateCompat_androidKt.java androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat.getCurrentSemanticsNodes AndroidComposeViewAccessibilityDelegateCompat.java androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat.createEvent$ui_release AndroidComposeViewAccessibilityDelegateCompat.java:34 androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat.sendEventForVirtualView AndroidComposeViewAccessibilityDelegateCompat.java:11 androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat.sendEventForVirtualView$default AndroidComposeViewAccessibilityDelegateCompat.java:6 androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat.sendSubtreeChangeAccessibilityEvents AndroidComposeViewAccessibilityDelegateCompat.java androidx.compose.ui.platform.AndroidComposeViewAccessibilityDelegateCompat.boundsUpdatesEventLoop AndroidComposeViewAccessibilityDelegateCompat.java androidx.compose.ui.platform.AndroidComposeView.boundsUpdatesEventLoop AndroidComposeView.java androidx.compose.ui.platform.WrappedComposition$setContent$1$1$1.invokeSuspend WrappedComposition.java kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith BaseContinuationImpl.java:8 kotlinx.coroutines.DispatchedTask.run DispatchedTask.java:100 androidx.compose.ui.platform.AndroidUiDispatcher.performTrampolineDispatch AndroidUiDispatcher.java androidx.compose.ui.platform.AndroidUiDispatcher.access$performTrampolineDispatch AndroidUiDispatcher.java androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.run AndroidUiDispatcher.java:2 android.os.Handler.handleCallback Handler.java:883
Useful note: had gotten this about a week ago when building the app:
Could not resolve com.github.commandiron:WheelPickerCompose:1.1.10.
> Could not get resource 'https://jitpack.io/com/github/commandiron/WheelPickerCompose/1.1.10/WheelPickerCompose-1.1.10.pom'.
> Could not GET 'https://jitpack.io/com/github/commandiron/WheelPickerCompose/1.1.10/WheelPickerCompose-1.1.10.pom'.
> Read timed out
Hi, i think we can support other calendar systems by adding another parameter like "dateSystem".
I don't think it requires much changes.
Just adding corresponding year-range, months and days range
This is a good library that save my life time.
I walked around your code and found that you removed the infinite loop feature in version 1.0.4 .
I thought there must be some reasons made you did this. But I didn't find the reason. Can you explain this, please. Or, if it was some bugs, do you have any plans to add it back to this awesome library?
Is there a chance you can remove internal from TextWheelPicker? I would like to use your lib as it looks neat and is full compose built, however text picker is kinda required for me e.g. For gender selection.
I used WheelTextPicker. but when I scroll numbers , the wheel returns to first item. I mean it doesn't save the state
@Composable
fun WheelPicker()
{
// FIXME: meaningless mutable state for output only?
var snappedDT:LocalDateTime by remember { mutableStateOf(LocalDateTime.MIN) }
var snappedD:LocalDate by remember { mutableStateOf(LocalDate.MIN) }
var snappedT:LocalTime by remember { mutableStateOf(LocalTime.MIN) }
Column {
WheelDateTimePicker(
startDateTime = LocalDateTime.of(
2025, 10, 20, 5, 30
),
minDateTime = LocalDateTime.now(),
maxDateTime = LocalDateTime.of(
2025, 10, 20, 5, 30
),
timeFormat = TimeFormat.AM_PM,
size = DpSize(200.dp, 100.dp),
rowCount = 5,
textStyle = MaterialTheme.typography.titleSmall,
textColor = Color(0xFFffc300),
selectorProperties = WheelPickerDefaults.selectorProperties(
enabled = true,
shape = RoundedCornerShape(0.dp),
color = Color(0xFFf1faee).copy(alpha = 0.2f),
border = BorderStroke(2.dp, Color(0xFFf1faee))
)
) { snappedDateTime -> snappedDT = snappedDateTime }
WheelDateTimePicker { snappedDateTime -> snappedDT = snappedDateTime}
WheelDatePicker { snappedDate -> snappedD = snappedDate }
WheelTimePicker { snappedTime -> snappedT = snappedTime }
WheelTimePicker(timeFormat = TimeFormat.AM_PM) { snappedTime -> snappedT = snappedTime }
WheelTextPicker(texts = (0..99).toList().map { it.toString() }, rowCount = 5, startIndex = 21)
}
}
It positions the element like that:
After touching it with mouse it repositions it properly:
When the rowCount is even, then the middle two rows are highlighted. Odd count gives correct behavior
I am enjoying the WheelPicker. I would like to request the option to hide the year if there is only 1 option.
My use case is that I would like my users to be able to select a date and time in the up coming week. Unless we are heading into the new year, most of the time, the year is obvious and does not need to be displayed.
Google pixel 3 Android 12
Running on my phone does not have the same bending effect as the example you provided
but rather a straight one
May I ask how I can solve it
1,只要年月模式,怎么控制
2,中间的选中的样式,怎么修改
Delay during setting the start date when opening the date picker
I have another small requirement in my project to have an ability to hide date, and only have month
year
selector.
I have noticed you are hiding year if the range was null, so I made a small change following the same idea in my fork with the date case.
Do you think it can be added?
It would be great if the WheelPicker would be combined with TextField. The central number inside the WheelPicker is editable as the text in TextField, with text validation for available items. As you type it when it finds the available element wheel positions to it. After you press enter or done cursor goes away, if the element was found wheel was already positioned, if no such element exception is thrown.
Actually, I cannot see WheelPicker without typing ability, for me it's "must have"! And probably I've seen this somewhere already.
I would like to manually change the time on a button click, for instance:
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
var changeableTime: LocalTime by remember {
mutableStateOf(LocalTime.now())
}
WheelTimePicker(
startTime = changeableTime,
timeFormat = TimeFormat.HOUR_24,
size = DpSize(200.dp, 100.dp),
rowCount = 5,
textStyle = MaterialTheme.typography.titleSmall,
textColor = Color(0xFFffc300),
selectorProperties = WheelPickerDefaults.selectorProperties(
enabled = true,
shape = RoundedCornerShape(0.dp),
color = Color(0xFFf1faee).copy(alpha = 0.2f),
border = BorderStroke(2.dp, Color(0xFFf1faee))
)
){ snappedDateTime ->
// Do something with snapped time
}
Button(onClick = {
changeableTime = LocalTime.now()
}) {
Text(text = "Set time to now")
}
}
Unfortunately the WheelTimePicker
does not get recomposed when startTime
is mutable and changed.
Should this work using the library or is this out of scope?
I would like to support AM and PM as well as 24-hour format. Is this something you are considering?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.