Skip to content

Commit 80154a1

Browse files
authored
Adds code for custom rotary (#714)
1 parent 2b314af commit 80154a1

File tree

1 file changed

+63
-2
lines changed
  • wear/src/main/java/com/example/wear/snippets/m3/rotary

1 file changed

+63
-2
lines changed

wear/src/main/java/com/example/wear/snippets/m3/rotary/Rotary.kt

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,11 @@ import androidx.compose.foundation.layout.size
2929
import androidx.compose.foundation.layout.width
3030
import androidx.compose.runtime.Composable
3131
import androidx.compose.runtime.LaunchedEffect
32+
import androidx.compose.runtime.State
3233
import androidx.compose.runtime.derivedStateOf
3334
import androidx.compose.runtime.getValue
3435
import androidx.compose.runtime.mutableIntStateOf
36+
import androidx.compose.runtime.mutableStateOf
3537
import androidx.compose.runtime.remember
3638
import androidx.compose.runtime.rememberCoroutineScope
3739
import androidx.compose.runtime.setValue
@@ -42,8 +44,11 @@ import androidx.compose.ui.focus.focusRequester
4244
import androidx.compose.ui.input.pointer.pointerInteropFilter
4345
import androidx.compose.ui.input.rotary.onRotaryScrollEvent
4446
import androidx.compose.ui.unit.dp
47+
import androidx.lifecycle.ViewModel
48+
import androidx.lifecycle.viewmodel.compose.viewModel
4549
import androidx.wear.compose.foundation.lazy.ScalingLazyColumn
4650
import androidx.wear.compose.foundation.lazy.ScalingLazyColumnDefaults
51+
import androidx.wear.compose.foundation.lazy.TransformingLazyColumn
4752
import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
4853
import androidx.wear.compose.foundation.lazy.rememberTransformingLazyColumnState
4954
import androidx.wear.compose.material3.Button
@@ -57,6 +62,7 @@ import androidx.wear.compose.material3.Text
5762
import androidx.wear.compose.material3.rememberPickerState
5863
import androidx.wear.compose.ui.tooling.preview.WearPreviewDevices
5964
import androidx.wear.compose.ui.tooling.preview.WearPreviewFontScales
65+
import kotlinx.coroutines.flow.MutableStateFlow
6066
import 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

Comments
 (0)