Skip to content

Commit 04888ec

Browse files
committed
Updates Navigation snippet for m3 version and create mirror folder for all the snippets for m3
Part of b/399354342 Change-Id: Iba0ccf5a0eb537e5dc6ac0f85c29e606ad509389
1 parent eb29ebd commit 04888ec

File tree

11 files changed

+835
-10
lines changed

11 files changed

+835
-10
lines changed

gradle/libs.versions.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ google-maps = "19.0.0"
3232
gradle-versions = "0.52.0"
3333
guava = "33.4.0-jre"
3434
hilt = "2.55"
35-
horologist = "0.6.22"
35+
horologist = "0.7.10-alpha"
3636
junit = "4.13.2"
3737
kotlin = "2.1.10"
3838
kotlinxSerializationJson = "1.8.0"
@@ -54,6 +54,7 @@ version-catalog-update = "0.8.5"
5454
wear = "1.3.0"
5555
wearComposeFoundation = "1.4.1"
5656
wearComposeMaterial = "1.4.1"
57+
wearComposeMaterial3 = "1.0.0-alpha32"
5758
wearToolingPreview = "1.0.0"
5859

5960
[libraries]
@@ -126,7 +127,7 @@ androidx-window-core = { module = "androidx.window:window-core", version.ref = "
126127
androidx-work-runtime-ktx = "androidx.work:work-runtime-ktx:2.10.0"
127128
coil-kt-compose = { module = "io.coil-kt:coil-compose", version.ref = "coil" }
128129
compose-foundation = { module = "androidx.wear.compose:compose-foundation", version.ref = "wearComposeFoundation" }
129-
compose-material = { module = "androidx.wear.compose:compose-material", version.ref = "wearComposeMaterial" }
130+
wear-compose-material = { module = "androidx.wear.compose:compose-material", version.ref = "wearComposeMaterial" }
130131
compose-ui-tooling = { module = "androidx.wear.compose:compose-ui-tooling", version.ref = "composeUiTooling" }
131132
glide-compose = { module = "com.github.bumptech.glide:compose", version.ref = "glide" }
132133
google-android-material = { module = "com.google.android.material:material", version.ref = "material" }
@@ -143,6 +144,7 @@ kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutine
143144
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" }
144145
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }
145146
play-services-wearable = { module = "com.google.android.gms:play-services-wearable", version.ref = "playServicesWearable" }
147+
wear-compose-material3 = { module = "androidx.wear.compose:compose-material3", version.ref = "wearComposeMaterial3" }
146148

147149
[plugins]
148150
android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }

wear/build.gradle.kts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ dependencies {
6969
implementation(platform(libs.androidx.compose.bom))
7070
implementation(libs.androidx.compose.ui)
7171
implementation(libs.androidx.compose.ui.tooling.preview)
72-
implementation(libs.compose.material)
72+
implementation(libs.wear.compose.material)
73+
implementation(libs.wear.compose.material3)
7374
implementation(libs.compose.foundation)
7475
implementation(libs.androidx.activity.compose)
7576
implementation(libs.androidx.core.splashscreen)

wear/src/main/AndroidManifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
android:value="true" />
2525

2626
<activity
27-
android:name=".snippets.MainActivity"
27+
android:name=".snippets.m3.MainActivity"
2828
android:exported="true"
2929
android:taskAffinity=""
3030
android:theme="@android:style/Theme.DeviceDefault">
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright 2021 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.wear.snippets.m3
18+
19+
import android.os.Bundle
20+
import androidx.activity.ComponentActivity
21+
import androidx.activity.compose.setContent
22+
import androidx.compose.runtime.Composable
23+
import com.example.wear.snippets.list.ComposeList
24+
import com.example.wear.snippets.m3.navigation.navigation
25+
26+
class MainActivity : ComponentActivity() {
27+
override fun onCreate(savedInstanceState: Bundle?) {
28+
super.onCreate(savedInstanceState)
29+
30+
setContent {
31+
WearApp()
32+
}
33+
}
34+
}
35+
36+
@Composable
37+
fun WearApp() {
38+
// insert here the snippet you want to test
39+
// navigation()
40+
}
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/*
2+
* Copyright 2022 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.wear.snippets.m3.list
18+
19+
import androidx.compose.material.icons.Icons
20+
import androidx.compose.material.icons.filled.Build
21+
import androidx.compose.runtime.Composable
22+
import androidx.compose.ui.platform.LocalConfiguration
23+
import androidx.wear.compose.material.Text
24+
import androidx.wear.compose.ui.tooling.preview.WearPreviewDevices
25+
import androidx.wear.compose.ui.tooling.preview.WearPreviewFontScales
26+
import com.google.android.horologist.annotations.ExperimentalHorologistApi
27+
import com.google.android.horologist.compose.layout.ScalingLazyColumn
28+
import com.google.android.horologist.compose.layout.ScalingLazyColumnDefaults
29+
import com.google.android.horologist.compose.layout.ScalingLazyColumnState
30+
import com.google.android.horologist.compose.layout.ScreenScaffold
31+
import com.google.android.horologist.compose.layout.rememberResponsiveColumnState
32+
import com.google.android.horologist.compose.material.Button
33+
import com.google.android.horologist.compose.material.ListHeaderDefaults.firstItemPadding
34+
import com.google.android.horologist.compose.material.ResponsiveListHeader
35+
36+
@OptIn(ExperimentalHorologistApi::class)
37+
@Composable
38+
fun ComposeList() {
39+
// [START android_wear_list]
40+
val columnState = rememberResponsiveColumnState(
41+
contentPadding = ScalingLazyColumnDefaults.padding(
42+
first = ScalingLazyColumnDefaults.ItemType.Text,
43+
last = ScalingLazyColumnDefaults.ItemType.SingleButton
44+
)
45+
)
46+
ScreenScaffold(scrollState = columnState) {
47+
ScalingLazyColumn(
48+
columnState = columnState
49+
) {
50+
item {
51+
ResponsiveListHeader(contentPadding = firstItemPadding()) {
52+
Text(text = "Header")
53+
}
54+
}
55+
// ... other items
56+
item {
57+
Button(
58+
imageVector = Icons.Default.Build,
59+
contentDescription = "Example Button",
60+
onClick = { }
61+
)
62+
}
63+
}
64+
}
65+
// [END android_wear_list]
66+
}
67+
68+
@OptIn(ExperimentalHorologistApi::class)
69+
@Composable
70+
fun SnapAndFlingComposeList() {
71+
// [START android_wear_snap]
72+
val columnState = rememberResponsiveColumnState(
73+
// ...
74+
// [START_EXCLUDE]
75+
contentPadding = ScalingLazyColumnDefaults.padding(
76+
first = ScalingLazyColumnDefaults.ItemType.Text,
77+
last = ScalingLazyColumnDefaults.ItemType.SingleButton
78+
),
79+
// [END_EXCLUDE]
80+
rotaryMode = ScalingLazyColumnState.RotaryMode.Snap
81+
)
82+
ScreenScaffold(scrollState = columnState) {
83+
ScalingLazyColumn(
84+
columnState = columnState
85+
) {
86+
// ...
87+
// [START_EXCLUDE]
88+
item {
89+
ResponsiveListHeader(contentPadding = firstItemPadding()) {
90+
Text(text = "Header")
91+
}
92+
}
93+
// ... other items
94+
item {
95+
Button(
96+
imageVector = Icons.Default.Build,
97+
contentDescription = "Example Button",
98+
onClick = { }
99+
)
100+
}
101+
// [END_EXCLUDE]
102+
}
103+
}
104+
// [END android_wear_snap]
105+
}
106+
107+
// [START android_wear_list_breakpoint]
108+
const val LARGE_DISPLAY_BREAKPOINT = 225
109+
110+
@Composable
111+
fun isLargeDisplay() =
112+
LocalConfiguration.current.screenWidthDp >= LARGE_DISPLAY_BREAKPOINT
113+
114+
// [START_EXCLUDE]
115+
@Composable
116+
fun breakpointDemo() {
117+
// [END_EXCLUDE]
118+
// ... use in your Composables:
119+
if (isLargeDisplay()) {
120+
// Show additional content.
121+
} else {
122+
// Show content only for smaller displays.
123+
}
124+
// [START_EXCLUDE]
125+
}
126+
// [END_EXCLUDE]
127+
// [END android_wear_list_breakpoint]
128+
129+
// [START android_wear_list_preview]
130+
@WearPreviewDevices
131+
@WearPreviewFontScales
132+
@Composable
133+
fun ComposeListPreview() {
134+
ComposeList()
135+
}
136+
// [END android_wear_list_preview]
137+
138+
@WearPreviewDevices
139+
@WearPreviewFontScales
140+
@Composable
141+
fun SnapAndFlingComposeListPreview() {
142+
SnapAndFlingComposeList()
143+
}
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
/*
2+
* Copyright 2022 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.wear.snippets.m3.navigation
18+
19+
import androidx.compose.foundation.layout.fillMaxSize
20+
import androidx.compose.foundation.layout.fillMaxWidth
21+
import androidx.compose.runtime.Composable
22+
import androidx.compose.ui.Modifier
23+
import androidx.compose.ui.res.stringResource
24+
import androidx.compose.ui.text.style.TextAlign
25+
import androidx.wear.compose.foundation.lazy.TransformingLazyColumn
26+
import androidx.wear.compose.foundation.lazy.rememberTransformingLazyColumnState
27+
import androidx.wear.compose.material3.Text
28+
import androidx.wear.compose.material3.AppScaffold
29+
import androidx.wear.compose.material3.Button
30+
import androidx.wear.compose.material3.ListHeader
31+
import androidx.wear.compose.material3.ScreenScaffold
32+
import androidx.wear.compose.navigation.SwipeDismissableNavHost
33+
import androidx.wear.compose.navigation.composable
34+
import androidx.wear.compose.navigation.rememberSwipeDismissableNavController
35+
import androidx.wear.compose.ui.tooling.preview.WearPreviewDevices
36+
import androidx.wear.compose.ui.tooling.preview.WearPreviewFontScales
37+
import com.example.wear.R
38+
import com.google.android.horologist.compose.layout.ColumnItemType
39+
import com.google.android.horologist.compose.layout.rememberResponsiveColumnPadding
40+
41+
@Composable
42+
fun navigation() {
43+
// [START android_wear_navigation]
44+
AppScaffold {
45+
val navController = rememberSwipeDismissableNavController()
46+
SwipeDismissableNavHost(
47+
navController = navController,
48+
startDestination = "message_list"
49+
) {
50+
composable("message_list") {
51+
MessageList(onMessageClick = { id ->
52+
navController.navigate("message_detail/$id")
53+
})
54+
}
55+
composable("message_detail/{id}") {
56+
MessageDetail(id = it.arguments?.getString("id")!!)
57+
}
58+
}
59+
}
60+
// [START_EXCLUDE]
61+
}
62+
63+
@Composable
64+
fun MessageDetail(id: String) {
65+
// [END_EXCLUDE]
66+
// .. Screen level content goes here
67+
val scrollState = rememberTransformingLazyColumnState()
68+
69+
val padding = rememberResponsiveColumnPadding(
70+
first = ColumnItemType.BodyText
71+
)
72+
73+
ScreenScaffold(
74+
scrollState = scrollState,
75+
contentPadding = padding
76+
) {
77+
// Screen content goes here
78+
// [END android_wear_navigation]
79+
TransformingLazyColumn(state = scrollState) {
80+
item {
81+
Text(
82+
text = id,
83+
textAlign = TextAlign.Center,
84+
modifier = Modifier.fillMaxSize()
85+
)
86+
}
87+
}
88+
}
89+
}
90+
91+
@Composable
92+
fun MessageList(onMessageClick: (String) -> Unit) {
93+
val scrollState = rememberTransformingLazyColumnState()
94+
95+
val padding = rememberResponsiveColumnPadding(
96+
first = ColumnItemType.ListHeader,
97+
last = ColumnItemType.Button
98+
)
99+
100+
ScreenScaffold(scrollState = scrollState, contentPadding = padding) { contentPadding ->
101+
TransformingLazyColumn(
102+
state = scrollState,
103+
contentPadding = contentPadding
104+
) {
105+
item {
106+
ListHeader() {
107+
Text(text = stringResource(R.string.message_list))
108+
}
109+
}
110+
item {
111+
Button(
112+
onClick = { onMessageClick("message1") },
113+
modifier = Modifier.fillMaxWidth()
114+
) {
115+
Text(text = "Message 1")
116+
}
117+
}
118+
item {
119+
Button(
120+
onClick = { onMessageClick("message2") },
121+
modifier = Modifier.fillMaxWidth()
122+
) {
123+
Text(text = "Message 2")
124+
}
125+
}
126+
}
127+
}
128+
}
129+
130+
@WearPreviewDevices
131+
@WearPreviewFontScales
132+
@Composable
133+
fun MessageDetailPreview() {
134+
MessageDetail("test")
135+
}
136+
137+
@WearPreviewDevices
138+
@WearPreviewFontScales
139+
@Composable
140+
fun MessageListPreview() {
141+
MessageList(onMessageClick = {})
142+
}

0 commit comments

Comments
 (0)