diff --git a/ComposeAdvanced/app/src/main/java/com/example/android/wearable/composeadvanced/presentation/MainActivity.kt b/ComposeAdvanced/app/src/main/java/com/example/android/wearable/composeadvanced/presentation/MainActivity.kt index 98ab07079..dc0312f12 100644 --- a/ComposeAdvanced/app/src/main/java/com/example/android/wearable/composeadvanced/presentation/MainActivity.kt +++ b/ComposeAdvanced/app/src/main/java/com/example/android/wearable/composeadvanced/presentation/MainActivity.kt @@ -22,6 +22,7 @@ import androidx.compose.foundation.background import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier @@ -49,6 +50,9 @@ import com.example.android.wearable.composeadvanced.presentation.theme.WearAppTh import com.example.android.wearable.composeadvanced.presentation.ui.ScalingLazyListStateViewModel import com.example.android.wearable.composeadvanced.presentation.ui.ScrollStateViewModel import com.example.android.wearable.composeadvanced.presentation.ui.landing.LandingScreen +import com.example.android.wearable.composeadvanced.presentation.ui.userinput.SliderScreen +import com.example.android.wearable.composeadvanced.presentation.ui.userinput.StepperScreen +import com.example.android.wearable.composeadvanced.presentation.ui.userinput.UserInputComponentsScreen import com.example.android.wearable.composeadvanced.presentation.ui.watch.WatchDetailScreen import com.example.android.wearable.composeadvanced.presentation.ui.watchlist.WatchListScreen @@ -113,6 +117,12 @@ fun WearApp(watchRepository: WatchRepository) { currentBackStackEntry?.arguments?.getSerializable(SCROLL_TYPE_NAV_ARGUMENT) ?: DestinationScrollType.NONE + // TODO: consider moving to ViewModel + // Display value is passed down to various user input screens, for the slider and stepper + // components specifically, to demonstrate how they work. + val defaultSelectedValue = 2 + var displayValueForUserInput by remember { mutableStateOf(defaultSelectedValue) } + Scaffold( timeText = { // Scaffold places time at top of screen to follow Material Design guidelines. @@ -184,6 +194,9 @@ fun WearApp(watchRepository: WatchRepository) { onClickWatchList = { swipeDismissableNavController.navigate(Screen.WatchList.route) }, + onClickDemoUserInputComponents = { + swipeDismissableNavController.navigate(Screen.UserInputComponents.route) + }, proceedingTimeTextEnabled = showProceedingTextBeforeTime, onClickProceedingTimeText = { showProceedingTextBeforeTime = !showProceedingTextBeforeTime @@ -191,6 +204,36 @@ fun WearApp(watchRepository: WatchRepository) { ) } + composable(Screen.UserInputComponents.route) { + UserInputComponentsScreen( + value = displayValueForUserInput, + onClickStepper = { + swipeDismissableNavController.navigate(Screen.Stepper.route) + }, + onClickSlider = { + swipeDismissableNavController.navigate(Screen.Slider.route) + } + ) + } + + composable(Screen.Stepper.route) { + StepperScreen( + displayValue = displayValueForUserInput, + onValueChange = { + displayValueForUserInput = it + } + ) + } + + composable(Screen.Slider.route) { + SliderScreen( + displayValue = displayValueForUserInput, + onValueChange = { + displayValueForUserInput = it + } + ) + } + composable( route = Screen.WatchList.route, arguments = listOf( diff --git a/ComposeAdvanced/app/src/main/java/com/example/android/wearable/composeadvanced/presentation/navigation/Screen.kt b/ComposeAdvanced/app/src/main/java/com/example/android/wearable/composeadvanced/presentation/navigation/Screen.kt index 80b82c42e..c22fd78c9 100644 --- a/ComposeAdvanced/app/src/main/java/com/example/android/wearable/composeadvanced/presentation/navigation/Screen.kt +++ b/ComposeAdvanced/app/src/main/java/com/example/android/wearable/composeadvanced/presentation/navigation/Screen.kt @@ -32,4 +32,7 @@ sealed class Screen( object Landing : Screen("landing") object WatchList : Screen("watchList") object WatchDetail : Screen("watchDetail") + object UserInputComponents : Screen("userInputComponents") + object Stepper : Screen("stepper") + object Slider : Screen("slider") } diff --git a/ComposeAdvanced/app/src/main/java/com/example/android/wearable/composeadvanced/presentation/ui/landing/LandingScreen.kt b/ComposeAdvanced/app/src/main/java/com/example/android/wearable/composeadvanced/presentation/ui/landing/LandingScreen.kt index 8c7e6e321..d3987d4fb 100644 --- a/ComposeAdvanced/app/src/main/java/com/example/android/wearable/composeadvanced/presentation/ui/landing/LandingScreen.kt +++ b/ComposeAdvanced/app/src/main/java/com/example/android/wearable/composeadvanced/presentation/ui/landing/LandingScreen.kt @@ -19,12 +19,10 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -45,8 +43,8 @@ import androidx.wear.compose.material.ToggleChip import com.example.android.wearable.composeadvanced.R /** - * Simple landing page with two actions, view a list of watches or toggle on/off text before the - * time. + * Simple landing page with three actions, view a list of watches, toggle on/off text before the + * time or view a demo of different user input components. * * A text label indicates the screen shape and places it at the bottom of the screen. * If it's a round device, it will curve the text along the bottom curve. Otherwise, for a square @@ -55,6 +53,7 @@ import com.example.android.wearable.composeadvanced.R @Composable fun LandingScreen( onClickWatchList: () -> Unit, + onClickDemoUserInputComponents: () -> Unit, proceedingTimeTextEnabled: Boolean, onClickProceedingTimeText: (Boolean) -> Unit, ) { @@ -66,7 +65,7 @@ fun LandingScreen( modifier = Modifier .fillMaxSize() .padding(horizontal = 10.dp), - verticalArrangement = Arrangement.Center + verticalArrangement = Arrangement.spacedBy(4.dp, Alignment.CenterVertically) ) { CompactChip( onClick = onClickWatchList, @@ -79,8 +78,6 @@ fun LandingScreen( } ) - Spacer(modifier = Modifier.size(4.dp)) - ToggleChip( modifier = Modifier.height(32.dp), checked = proceedingTimeTextEnabled, @@ -93,6 +90,17 @@ fun LandingScreen( ) } ) + + CompactChip( + onClick = onClickDemoUserInputComponents, + label = { + Text( + stringResource(R.string.user_input_components_label), + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + } + ) } // Places curved text at the bottom of round devices and straight text at the bottom of diff --git a/ComposeAdvanced/app/src/main/java/com/example/android/wearable/composeadvanced/presentation/ui/userinput/SliderScreen.kt b/ComposeAdvanced/app/src/main/java/com/example/android/wearable/composeadvanced/presentation/ui/userinput/SliderScreen.kt new file mode 100644 index 000000000..9080100bc --- /dev/null +++ b/ComposeAdvanced/app/src/main/java/com/example/android/wearable/composeadvanced/presentation/ui/userinput/SliderScreen.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.android.wearable.composeadvanced.presentation.ui.userinput + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import androidx.wear.compose.material.InlineSlider + +/** + * Displays a Slider, which allows users to make a selection from a range of values. + */ +@Composable +fun SliderScreen( + displayValue: Int, + onValueChange: (Int) -> Unit +) { + Column( + modifier = Modifier + .fillMaxSize() + .padding(top = 10.dp), + verticalArrangement = Arrangement.Center + ) { + InlineSlider( + value = displayValue, + onValueChange = onValueChange, + valueProgression = 1..10, + segmented = true + ) + } +} diff --git a/ComposeAdvanced/app/src/main/java/com/example/android/wearable/composeadvanced/presentation/ui/userinput/StepperScreen.kt b/ComposeAdvanced/app/src/main/java/com/example/android/wearable/composeadvanced/presentation/ui/userinput/StepperScreen.kt new file mode 100644 index 000000000..b7d77f556 --- /dev/null +++ b/ComposeAdvanced/app/src/main/java/com/example/android/wearable/composeadvanced/presentation/ui/userinput/StepperScreen.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.android.wearable.composeadvanced.presentation.ui.userinput + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import androidx.wear.compose.material.Stepper +import androidx.wear.compose.material.Text + +/** + * Displays a Stepper, which allows users to make a selection from a range of values. + */ +@Composable +fun StepperScreen( + displayValue: Int, + onValueChange: (Int) -> Unit +) { + Column( + modifier = Modifier + .fillMaxSize() + .padding(top = 10.dp), + verticalArrangement = Arrangement.Center + ) { + Stepper( + value = displayValue, + onValueChange = onValueChange, + valueProgression = 1..10 + ) { Text("Value: $displayValue") } + } +} diff --git a/ComposeAdvanced/app/src/main/java/com/example/android/wearable/composeadvanced/presentation/ui/userinput/UserInputComponentsScreen.kt b/ComposeAdvanced/app/src/main/java/com/example/android/wearable/composeadvanced/presentation/ui/userinput/UserInputComponentsScreen.kt new file mode 100644 index 000000000..a8a3deeff --- /dev/null +++ b/ComposeAdvanced/app/src/main/java/com/example/android/wearable/composeadvanced/presentation/ui/userinput/UserInputComponentsScreen.kt @@ -0,0 +1,78 @@ +/* + * Copyright 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.android.wearable.composeadvanced.presentation.ui.userinput + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.wear.compose.material.CompactChip +import androidx.wear.compose.material.Text +import com.example.android.wearable.composeadvanced.R + +/** + * Displays a value by using a Stepper or a Slider + */ +@Composable +fun UserInputComponentsScreen( + value: Int, + onClickStepper: () -> Unit, + onClickSlider: () -> Unit +) { + Column( + modifier = Modifier + .fillMaxSize() + .padding(vertical = 10.dp) + .padding(horizontal = 10.dp), + verticalArrangement = Arrangement.spacedBy(4.dp, Alignment.CenterVertically) + ) { + Text( + modifier = Modifier.fillMaxWidth(1f), + text = "${stringResource(R.string.selected_value)}: $value", + textAlign = TextAlign.Center + ) + + CompactChip( + onClick = onClickStepper, + label = { + Text( + stringResource(R.string.stepper_label), + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + } + ) + + CompactChip( + onClick = onClickSlider, + label = { + Text( + stringResource(R.string.slider_label), + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + } + ) + } +} diff --git a/ComposeAdvanced/app/src/main/res/values/strings.xml b/ComposeAdvanced/app/src/main/res/values/strings.xml index bf009152c..a50d54395 100644 --- a/ComposeAdvanced/app/src/main/res/values/strings.xml +++ b/ComposeAdvanced/app/src/main/res/values/strings.xml @@ -25,4 +25,8 @@ Vignette Invalid Watch Leading Text... + Stepper + Slider + User Input Components + Selected Value