@@ -29,9 +29,11 @@ import androidx.compose.foundation.layout.size
2929import androidx.compose.foundation.layout.width
3030import androidx.compose.runtime.Composable
3131import androidx.compose.runtime.LaunchedEffect
32+ import androidx.compose.runtime.State
3233import androidx.compose.runtime.derivedStateOf
3334import androidx.compose.runtime.getValue
3435import androidx.compose.runtime.mutableIntStateOf
36+ import androidx.compose.runtime.mutableStateOf
3537import androidx.compose.runtime.remember
3638import androidx.compose.runtime.rememberCoroutineScope
3739import androidx.compose.runtime.setValue
@@ -42,8 +44,11 @@ import androidx.compose.ui.focus.focusRequester
4244import androidx.compose.ui.input.pointer.pointerInteropFilter
4345import androidx.compose.ui.input.rotary.onRotaryScrollEvent
4446import androidx.compose.ui.unit.dp
47+ import androidx.lifecycle.ViewModel
48+ import androidx.lifecycle.viewmodel.compose.viewModel
4549import androidx.wear.compose.foundation.lazy.ScalingLazyColumn
4650import androidx.wear.compose.foundation.lazy.ScalingLazyColumnDefaults
51+ import androidx.wear.compose.foundation.lazy.TransformingLazyColumn
4752import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
4853import androidx.wear.compose.foundation.lazy.rememberTransformingLazyColumnState
4954import androidx.wear.compose.material3.Button
@@ -57,6 +62,7 @@ import androidx.wear.compose.material3.Text
5762import androidx.wear.compose.material3.rememberPickerState
5863import androidx.wear.compose.ui.tooling.preview.WearPreviewDevices
5964import androidx.wear.compose.ui.tooling.preview.WearPreviewFontScales
65+ import kotlinx.coroutines.flow.MutableStateFlow
6066import kotlinx.coroutines.launch
6167
6268@Composable
@@ -105,7 +111,8 @@ fun TimePicker() {
105111 // [END_EXCLUDE]
106112 Picker (
107113 readOnly = selectedColumn != 0 ,
108- modifier = Modifier .size(64 .dp, 100 .dp)
114+ modifier = Modifier
115+ .size(64 .dp, 100 .dp)
109116 .onRotaryScrollEvent {
110117 coroutineScope.launch {
111118 hourState.scrollBy(it.verticalScrollPixels)
@@ -134,7 +141,8 @@ fun TimePicker() {
134141 // [END_EXCLUDE]
135142 Picker (
136143 readOnly = selectedColumn != 1 ,
137- modifier = Modifier .size(64 .dp, 100 .dp)
144+ modifier = Modifier
145+ .size(64 .dp, 100 .dp)
138146 .onRotaryScrollEvent {
139147 coroutineScope.launch {
140148 minuteState.scrollBy(it.verticalScrollPixels)
@@ -213,6 +221,59 @@ fun PositionScrollIndicator() {
213221 // [END android_wear_rotary_position_indicator]
214222}
215223
224+ @Composable
225+ fun VolumeScreen () {
226+ // [START android_wear_rotary_custom_ui]
227+ val focusRequester: FocusRequester = remember { FocusRequester () }
228+ val volumeViewModel: VolumeViewModel .MyViewModel =
229+ viewModel()
230+ val volumeState by volumeViewModel.volumeState
231+
232+ TransformingLazyColumn (
233+ modifier = Modifier
234+ .fillMaxSize()
235+ .onRotaryScrollEvent {
236+ volumeViewModel.onVolumeChangeByScroll(it.verticalScrollPixels)
237+ true
238+ }
239+ .focusRequester(focusRequester)
240+ .focusable(),
241+ ) {
242+ // You can use volumeState here, for example:
243+ item {
244+ Text (" Volume: $volumeState " )
245+ }
246+ }
247+ // [END android_wear_rotary_custom_ui]
248+ }
249+
250+ // [START android_wear_rotary_custom_model]
251+ class VolumeRange (
252+ val max : Int = 10 ,
253+ val min : Int = 0
254+ )
255+
256+ private object VolumeViewModel {
257+ class MyViewModel : ViewModel () {
258+ private val _volumeState = mutableIntStateOf(0 )
259+ val volumeState: State <Int >
260+ get() = _volumeState
261+
262+ // ...
263+ fun onVolumeChangeByScroll (pixels : Float ) {
264+ _volumeState .value = when {
265+ pixels > 0 -> minOf(volumeState.value + 1 , VolumeRange ().max)
266+ pixels < 0 -> maxOf(volumeState.value - 1 , VolumeRange ().min)
267+ else -> volumeState.value
268+ }
269+ }
270+ }
271+ }
272+ // [END android_wear_rotary_custom_model]
273+
274+
275+
276+
216277@WearPreviewDevices
217278@WearPreviewFontScales
218279@Composable
0 commit comments