16
16
17
17
package com.example.wear.snippets.rotary
18
18
19
- import android.view.MotionEvent
20
- import androidx.compose.foundation.focusable
21
- import androidx.compose.foundation.gestures.animateScrollBy
22
- import androidx.compose.foundation.gestures.scrollBy
23
- import androidx.compose.foundation.layout.Arrangement
24
- import androidx.compose.foundation.layout.Box
25
- import androidx.compose.foundation.layout.Row
26
- import androidx.compose.foundation.layout.Spacer
27
- import androidx.compose.foundation.layout.fillMaxSize
28
- import androidx.compose.foundation.layout.size
29
- import androidx.compose.foundation.layout.width
19
+ import androidx.compose.foundation.layout.fillMaxWidth
30
20
import androidx.compose.runtime.Composable
31
- import androidx.compose.runtime.LaunchedEffect
32
- import androidx.compose.runtime.derivedStateOf
33
- import androidx.compose.runtime.getValue
34
- import androidx.compose.runtime.mutableIntStateOf
35
- import androidx.compose.runtime.remember
36
- import androidx.compose.runtime.rememberCoroutineScope
37
- import androidx.compose.runtime.setValue
38
- import androidx.compose.ui.Alignment
39
- import androidx.compose.ui.ExperimentalComposeUiApi
40
21
import androidx.compose.ui.Modifier
41
- import androidx.compose.ui.focus.FocusRequester
42
- import androidx.compose.ui.focus.focusRequester
43
- import androidx.compose.ui.input.pointer.pointerInteropFilter
44
- import androidx.compose.ui.input.rotary.onRotaryScrollEvent
45
- import androidx.compose.ui.unit.dp
46
- import androidx.wear.compose.foundation.ExperimentalWearFoundationApi
47
22
import androidx.wear.compose.foundation.lazy.ScalingLazyColumn
23
+ import androidx.wear.compose.foundation.lazy.ScalingLazyColumnDefaults
48
24
import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
49
- import androidx.wear.compose.foundation.rememberActiveFocusRequester
50
25
import androidx.wear.compose.material.Chip
51
- import androidx.wear.compose.material.MaterialTheme
52
- import androidx.wear.compose.material.Picker
26
+ import androidx.wear.compose.material.ChipDefaults
27
+ import androidx.wear.compose.material.ListHeader
53
28
import androidx.wear.compose.material.PositionIndicator
54
29
import androidx.wear.compose.material.Scaffold
55
30
import androidx.wear.compose.material.Text
56
- import androidx.wear.compose.material.rememberPickerState
57
31
import androidx.wear.compose.ui.tooling.preview.WearPreviewDevices
58
32
import androidx.wear.compose.ui.tooling.preview.WearPreviewFontScales
59
- import kotlinx.coroutines.launch
60
33
61
34
@Composable
62
35
fun ScrollableScreen () {
63
36
// This sample doesn't add a Time Text at the top of the screen.
64
37
// If using Time Text, add padding to ensure content does not overlap with Time Text.
65
- }
66
-
67
- @OptIn(ExperimentalComposeUiApi ::class )
68
- @Composable
69
- fun TimePicker () {
70
- val textStyle = MaterialTheme .typography.display1
71
-
72
- // [START android_wear_rotary_input_picker]
73
- var selectedColumn by remember { mutableIntStateOf(0 ) }
74
-
75
- val hoursFocusRequester = remember { FocusRequester () }
76
- val minutesRequester = remember { FocusRequester () }
77
- // [START_EXCLUDE]
78
- val coroutineScope = rememberCoroutineScope()
38
+ // [START android_wear_rotary_input_snap_fling]
39
+ val listState = rememberScalingLazyListState()
40
+ Scaffold (
41
+ positionIndicator = {
42
+ PositionIndicator (scalingLazyListState = listState)
43
+ }
44
+ ) {
79
45
80
- @Composable
81
- fun Option (column : Int , text : String ) = Box (modifier = Modifier .fillMaxSize()) {
82
- Text (
83
- text = text, style = textStyle,
84
- color = if (selectedColumn == column) MaterialTheme .colors.secondary
85
- else MaterialTheme .colors.onBackground,
86
- modifier = Modifier
87
- .pointerInteropFilter {
88
- if (it.action == MotionEvent .ACTION_DOWN ) selectedColumn = column
89
- true
90
- }
91
- )
92
- }
93
- // [END_EXCLUDE]
94
- Scaffold (modifier = Modifier .fillMaxSize()) {
95
- Row (
96
- // [START_EXCLUDE]
97
- modifier = Modifier .fillMaxSize(),
98
- verticalAlignment = Alignment .CenterVertically ,
99
- horizontalArrangement = Arrangement .Center ,
100
- // [END_EXCLUDE]
101
- // ...
46
+ val state = rememberScalingLazyListState()
47
+ ScalingLazyColumn (
48
+ modifier = Modifier .fillMaxWidth(),
49
+ state = state,
50
+ flingBehavior = ScalingLazyColumnDefaults .snapFlingBehavior(state = state)
102
51
) {
52
+ // Content goes here
103
53
// [START_EXCLUDE]
104
- val hourState = rememberPickerState(
105
- initialNumberOfOptions = 12 ,
106
- initiallySelectedOption = 5
107
- )
108
- val hourContentDescription by remember {
109
- derivedStateOf { " ${hourState.selectedOption + 1 } hours" }
54
+ item { ListHeader { Text (text = " List Header" ) } }
55
+ items(20 ) {
56
+ Chip (
57
+ onClick = {},
58
+ label = { Text (" List item $it " ) },
59
+ colors = ChipDefaults .secondaryChipColors()
60
+ )
110
61
}
111
62
// [END_EXCLUDE]
112
- Picker (
113
- readOnly = selectedColumn != 0 ,
114
- modifier = Modifier .size(64 .dp, 100 .dp)
115
- .onRotaryScrollEvent {
116
- coroutineScope.launch {
117
- hourState.scrollBy(it.verticalScrollPixels)
118
- }
119
- true
120
- }
121
- .focusRequester(hoursFocusRequester)
122
- .focusable(),
123
- onSelected = { selectedColumn = 0 },
124
- // ...
125
- // [START_EXCLUDE]
126
- state = hourState,
127
- contentDescription = hourContentDescription,
128
- option = { hour: Int -> Option (0 , " %2d" .format(hour + 1 )) }
129
- // [END_EXCLUDE]
130
- )
131
- // [START_EXCLUDE]
132
- Spacer (Modifier .width(8 .dp))
133
- Text (text = " :" , style = textStyle, color = MaterialTheme .colors.onBackground)
134
- Spacer (Modifier .width(8 .dp))
135
- val minuteState =
136
- rememberPickerState(initialNumberOfOptions = 60 , initiallySelectedOption = 0 )
137
- val minuteContentDescription by remember {
138
- derivedStateOf { " ${minuteState.selectedOption} minutes" }
139
- }
140
- // [END_EXCLUDE]
141
- Picker (
142
- readOnly = selectedColumn != 1 ,
143
- modifier = Modifier .size(64 .dp, 100 .dp)
144
- .onRotaryScrollEvent {
145
- coroutineScope.launch {
146
- minuteState.scrollBy(it.verticalScrollPixels)
147
- }
148
- true
149
- }
150
- .focusRequester(minutesRequester)
151
- .focusable(),
152
- onSelected = { selectedColumn = 1 },
153
- // ...
154
- // [START_EXCLUDE]
155
- state = minuteState,
156
- contentDescription = minuteContentDescription,
157
- option = { minute: Int -> Option (1 , " %02d" .format(minute)) }
158
- // [END_EXCLUDE]
159
- )
160
- LaunchedEffect (selectedColumn) {
161
- listOf (
162
- hoursFocusRequester,
163
- minutesRequester
164
- )[selectedColumn]
165
- .requestFocus()
166
- }
167
63
}
168
64
}
169
- // [END android_wear_rotary_input_picker ]
65
+ // [END android_wear_rotary_input_snap_fling ]
170
66
}
171
67
172
68
@WearPreviewDevices
@@ -175,10 +71,3 @@ fun TimePicker() {
175
71
fun ScrollableScreenPreview () {
176
72
ScrollableScreen ()
177
73
}
178
-
179
- @WearPreviewDevices
180
- @WearPreviewFontScales
181
- @Composable
182
- fun TimePickerPreview () {
183
- TimePicker ()
184
- }
0 commit comments