Skip to content

Commit fd4d608

Browse files
Merge branch 'main' into jv/broadcast_receiver_new
2 parents 7f3ccc4 + fb654a9 commit fd4d608

File tree

8 files changed

+300
-0
lines changed

8 files changed

+300
-0
lines changed

compose/snippets/src/main/java/com/example/compose/snippets/layouts/PagerSnippets.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ fun PagerIndicator() {
413413
}
414414
}
415415

416+
// [START android_compose_autoadvancepager]
416417
@Composable
417418
fun AutoAdvancePager(pageItems: List<Color>, modifier: Modifier = Modifier) {
418419
Box(modifier = Modifier.fillMaxSize()) {
@@ -457,6 +458,7 @@ fun AutoAdvancePager(pageItems: List<Color>, modifier: Modifier = Modifier) {
457458
PagerIndicator(pageItems.size, pagerState.currentPage)
458459
}
459460
}
461+
// [END android_compose_autoadvancepager]
460462

461463
@Preview
462464
@Composable
@@ -470,6 +472,7 @@ private fun AutoAdvancePagerPreview() {
470472
AutoAdvancePager(pageItems = pageItems)
471473
}
472474

475+
// [START android_compose_pagerindicator]
473476
@Composable
474477
fun PagerIndicator(pageCount: Int, currentPageIndex: Int, modifier: Modifier = Modifier) {
475478
Box(modifier = Modifier.fillMaxSize()) {
@@ -494,6 +497,7 @@ fun PagerIndicator(pageCount: Int, currentPageIndex: Int, modifier: Modifier = M
494497
}
495498
}
496499
}
500+
// [END android_compose_pagerindicator]
497501

498502
@Preview
499503
@Composable
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
/*
2+
* Copyright 2024 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.compose.snippets.predictiveback
18+
19+
import android.os.SystemClock
20+
import androidx.activity.BackEventCompat
21+
import androidx.activity.compose.PredictiveBackHandler
22+
import androidx.compose.animation.EnterTransition
23+
import androidx.compose.animation.core.Animatable
24+
import androidx.compose.animation.scaleOut
25+
import androidx.compose.foundation.background
26+
import androidx.compose.foundation.layout.Box
27+
import androidx.compose.foundation.layout.fillMaxSize
28+
import androidx.compose.material3.Surface
29+
import androidx.compose.runtime.Composable
30+
import androidx.compose.runtime.getValue
31+
import androidx.compose.runtime.mutableFloatStateOf
32+
import androidx.compose.runtime.mutableStateOf
33+
import androidx.compose.runtime.remember
34+
import androidx.compose.runtime.rememberCoroutineScope
35+
import androidx.compose.runtime.setValue
36+
import androidx.compose.ui.Modifier
37+
import androidx.compose.ui.geometry.Offset
38+
import androidx.compose.ui.graphics.Color
39+
import androidx.compose.ui.graphics.TransformOrigin
40+
import androidx.compose.ui.input.pointer.util.VelocityTracker
41+
import androidx.compose.ui.platform.LocalDensity
42+
import androidx.compose.ui.unit.dp
43+
import androidx.navigation.NavHostController
44+
import androidx.navigation.compose.NavHost
45+
import androidx.navigation.compose.composable
46+
import androidx.navigation.compose.rememberNavController
47+
import kotlin.coroutines.cancellation.CancellationException
48+
import kotlinx.coroutines.flow.Flow
49+
50+
@Composable
51+
private fun PredictiveBackOverrideExit(
52+
modifier: Modifier,
53+
) {
54+
val navController = rememberNavController()
55+
56+
// [START android_compose_predictiveback_navhost]
57+
NavHost(
58+
navController = navController,
59+
startDestination = "home",
60+
popExitTransition = {
61+
scaleOut(
62+
targetScale = 0.9f,
63+
transformOrigin = TransformOrigin(pivotFractionX = 0.5f, pivotFractionY = 0.5f)
64+
)
65+
},
66+
popEnterTransition = {
67+
EnterTransition.None
68+
},
69+
modifier = modifier,
70+
)
71+
// [END android_compose_predictiveback_navhost]
72+
{
73+
composable("home") {
74+
HomeScreen(
75+
modifier = modifier,
76+
navController = navController,
77+
)
78+
}
79+
composable("settings") {
80+
SettingsScreen(
81+
modifier = modifier,
82+
navController = navController,
83+
)
84+
}
85+
}
86+
}
87+
88+
@Composable
89+
private fun HomeScreen(
90+
modifier: Modifier = Modifier,
91+
navController: NavHostController
92+
) {
93+
}
94+
95+
@Composable
96+
private fun SettingsScreen(
97+
modifier: Modifier = Modifier,
98+
navController: NavHostController
99+
) {
100+
}
101+
102+
@Composable
103+
private fun PredictiveBackHandlerBasicExample() {
104+
105+
var boxScale by remember { mutableFloatStateOf(1F) }
106+
107+
Box(
108+
modifier = Modifier
109+
.fillMaxSize(boxScale)
110+
.background(Color.Blue)
111+
)
112+
113+
// [START android_compose_predictivebackhandler_basic]
114+
PredictiveBackHandler(true) { progress: Flow<BackEventCompat> ->
115+
// code for gesture back started
116+
try {
117+
progress.collect { backEvent ->
118+
// code for progress
119+
boxScale = 1F - (1F * backEvent.progress)
120+
}
121+
// code for completion
122+
} catch (e: CancellationException) {
123+
// code for cancellation
124+
boxScale = 1F
125+
}
126+
}
127+
// [END android_compose_predictivebackhandler_basic]
128+
}
129+
130+
@Composable
131+
private fun PredictiveBackHandlerManualProgress() {
132+
133+
Surface(
134+
modifier = Modifier.fillMaxSize()
135+
) {
136+
var drawerState by remember {
137+
mutableStateOf(DrawerState.Closed)
138+
}
139+
140+
val translationX = remember {
141+
Animatable(0f)
142+
}
143+
144+
val drawerWidth = with(LocalDensity.current) {
145+
DrawerWidth.toPx()
146+
}
147+
translationX.updateBounds(0f, drawerWidth)
148+
149+
val coroutineScope = rememberCoroutineScope()
150+
151+
suspend fun closeDrawer(velocity: Float = 0f) {
152+
translationX.animateTo(targetValue = 0f, initialVelocity = velocity)
153+
drawerState = DrawerState.Closed
154+
}
155+
suspend fun openDrawer(velocity: Float = 0f) {
156+
translationX.animateTo(targetValue = drawerWidth, initialVelocity = velocity)
157+
drawerState = DrawerState.Open
158+
}
159+
160+
val velocityTracker = remember {
161+
VelocityTracker()
162+
}
163+
164+
// [START android_compose_predictivebackhandler_manualprogress]
165+
PredictiveBackHandler(drawerState == DrawerState.Open) { progress ->
166+
try {
167+
progress.collect { backEvent ->
168+
val targetSize = (drawerWidth - (drawerWidth * backEvent.progress))
169+
translationX.snapTo(targetSize)
170+
velocityTracker.addPosition(
171+
SystemClock.uptimeMillis(),
172+
Offset(backEvent.touchX, backEvent.touchY)
173+
)
174+
}
175+
closeDrawer(velocityTracker.calculateVelocity().x)
176+
} catch (e: CancellationException) {
177+
openDrawer(velocityTracker.calculateVelocity().x)
178+
}
179+
velocityTracker.resetTracking()
180+
}
181+
// [END android_compose_predictivebackhandler_manualprogress]
182+
}
183+
}
184+
185+
private enum class DrawerState {
186+
Open,
187+
Closed
188+
}
189+
190+
private val DrawerWidth = 300.dp

gradle/libs.versions.toml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ coroutines = "1.9.0"
3030
glide = "1.0.0-beta01"
3131
google-maps = "19.0.0"
3232
gradle-versions = "0.51.0"
33+
guava = "33.2.1-android"
3334
hilt = "2.52"
3435
horologist = "0.6.20"
3536
junit = "4.13.2"
@@ -44,12 +45,22 @@ media3 = "1.4.1"
4445
# @keep
4546
minSdk = "21"
4647
playServicesWearable = "18.2.0"
48+
protolayout = "1.3.0-alpha04"
49+
protolayoutExpression = "1.3.0-alpha04"
50+
protolayoutMaterial = "1.3.0-alpha04"
4751
recyclerview = "1.3.2"
4852
# @keep
4953
targetSdk = "34"
54+
tiles = "1.5.0-alpha04"
55+
tilesRenderer = "1.5.0-alpha04"
56+
tilesTesting = "1.5.0-alpha04"
57+
tilesTooling = "1.5.0-alpha04"
58+
tilesToolingPreview = "1.5.0-alpha04"
5059
version-catalog-update = "0.8.5"
60+
wear = "1.3.0"
5161
wearComposeFoundation = "1.4.0"
5262
wearComposeMaterial = "1.4.0"
63+
wearToolingPreview = "1.0.0"
5364

5465
[libraries]
5566
accompanist-adaptive = { module = "com.google.accompanist:accompanist-adaptive", version.ref = "accompanist" }
@@ -103,10 +114,20 @@ androidx-media3-common = { module = "androidx.media3:media3-common", version.ref
103114
androidx-media3-exoplayer = { module = "androidx.media3:media3-exoplayer", version.ref = "media3" }
104115
androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "androidx-navigation" }
105116
androidx-paging-compose = { module = "androidx.paging:paging-compose", version.ref = "androidx-paging" }
117+
androidx-protolayout = { module = "androidx.wear.protolayout:protolayout", version.ref = "protolayout" }
118+
androidx-protolayout-expression = { module = "androidx.wear.protolayout:protolayout-expression", version.ref = "protolayoutExpression" }
119+
androidx-protolayout-material = { module = "androidx.wear.protolayout:protolayout-material", version.ref = "protolayoutMaterial" }
106120
androidx-recyclerview = { module = "androidx.recyclerview:recyclerview", version.ref = "recyclerview" }
107121
androidx-test-core = { module = "androidx.test:core", version.ref = "androidx-test" }
108122
androidx-test-espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "androidx-test-espresso" }
109123
androidx-test-runner = "androidx.test:runner:1.6.2"
124+
androidx-tiles = { module = "androidx.wear.tiles:tiles", version.ref = "tiles" }
125+
androidx-tiles-renderer = { module = "androidx.wear.tiles:tiles-renderer", version.ref = "tilesRenderer" }
126+
androidx-tiles-testing = { module = "androidx.wear.tiles:tiles-testing", version.ref = "tilesTesting" }
127+
androidx-tiles-tooling = { module = "androidx.wear.tiles:tiles-tooling", version.ref = "tilesTooling" }
128+
androidx-tiles-tooling-preview = { module = "androidx.wear.tiles:tiles-tooling-preview", version.ref = "tilesToolingPreview" }
129+
androidx-wear = { module = "androidx.wear:wear", version.ref = "wear" }
130+
androidx-wear-tooling-preview = { module = "androidx.wear:wear-tooling-preview", version.ref = "wearToolingPreview" }
110131
androidx-window-core = { module = "androidx.window:window-core", version.ref = "androidx-window" }
111132
androidx-work-runtime-ktx = "androidx.work:work-runtime-ktx:2.10.0"
112133
coil-kt-compose = { module = "io.coil-kt:coil-compose", version.ref = "coil" }
@@ -117,6 +138,7 @@ glide-compose = { module = "com.github.bumptech.glide:compose", version.ref = "g
117138
google-android-material = { module = "com.google.android.material:material", version.ref = "material" }
118139
googlemaps-compose = { module = "com.google.maps.android:maps-compose", version.ref = "maps-compose" }
119140
googlemaps-maps = { module = "com.google.android.gms:play-services-maps", version.ref = "google-maps" }
141+
guava = { module = "com.google.guava:guava", version.ref = "guava" }
120142
hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" }
121143
hilt-compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hilt" }
122144
horologist-compose-layout = { module = "com.google.android.horologist:horologist-compose-layout", version.ref = "horologist" }

wear/build.gradle.kts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,17 @@ dependencies {
5555

5656
implementation(libs.compose.ui.tooling)
5757
implementation(libs.play.services.wearable)
58+
implementation(libs.androidx.tiles)
59+
implementation(libs.androidx.wear)
60+
implementation(libs.androidx.protolayout)
61+
implementation(libs.androidx.protolayout.material)
62+
implementation(libs.androidx.protolayout.expression)
63+
debugImplementation(libs.androidx.tiles.renderer)
64+
testImplementation(libs.androidx.tiles.testing)
65+
implementation(libs.androidx.wear.tooling.preview)
66+
implementation(libs.androidx.tiles.tooling.preview)
67+
debugImplementation(libs.androidx.tiles.tooling)
68+
implementation(libs.guava)
5869
implementation(platform(libs.androidx.compose.bom))
5970
implementation(libs.androidx.compose.ui)
6071
implementation(libs.androidx.compose.ui.tooling.preview)

wear/src/main/AndroidManifest.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,24 @@
3434
<category android:name="android.intent.category.LAUNCHER" />
3535
</intent-filter>
3636
</activity>
37+
38+
<!-- [START android_wear_tile_manifest] -->
39+
<service
40+
android:name=".snippets.tile.MyTileService"
41+
android:label="@string/tile_label"
42+
android:description="@string/tile_description"
43+
android:icon="@mipmap/ic_launcher"
44+
android:exported="true"
45+
android:permission="com.google.android.wearable.permission.BIND_TILE_PROVIDER">
46+
<intent-filter>
47+
<action android:name="androidx.wear.tiles.action.BIND_TILE_PROVIDER" />
48+
</intent-filter>
49+
50+
<meta-data android:name="androidx.wear.tiles.PREVIEW"
51+
android:resource="@drawable/tile_preview" />
52+
</service>
53+
<!-- [END android_wear_tile_manifest] -->
54+
3755
</application>
3856

3957
</manifest>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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.tile
18+
19+
import androidx.wear.protolayout.ColorBuilders.argb
20+
import androidx.wear.protolayout.ResourceBuilders.Resources
21+
import androidx.wear.protolayout.TimelineBuilders.Timeline
22+
import androidx.wear.protolayout.material.Text
23+
import androidx.wear.protolayout.material.Typography
24+
import androidx.wear.tiles.RequestBuilders
25+
import androidx.wear.tiles.RequestBuilders.ResourcesRequest
26+
import androidx.wear.tiles.TileBuilders.Tile
27+
import androidx.wear.tiles.TileService
28+
import com.google.common.util.concurrent.Futures
29+
30+
private const val RESOURCES_VERSION = "1"
31+
32+
// [START android_wear_tile_mytileservice]
33+
class MyTileService : TileService() {
34+
35+
override fun onTileRequest(requestParams: RequestBuilders.TileRequest) =
36+
Futures.immediateFuture(Tile.Builder()
37+
.setResourcesVersion(RESOURCES_VERSION)
38+
.setTileTimeline(
39+
Timeline.fromLayoutElement(
40+
Text.Builder(this, "Hello World!")
41+
.setTypography(Typography.TYPOGRAPHY_BODY1)
42+
.setColor(argb(0xFFFFFFFF.toInt()))
43+
.build()))
44+
.build())
45+
46+
override fun onTileResourcesRequest(requestParams: ResourcesRequest) =
47+
Futures.immediateFuture(Resources.Builder()
48+
.setVersion(RESOURCES_VERSION)
49+
.build()
50+
)
51+
52+
}
53+
// [END android_wear_tile_mytileservice]
7.16 KB
Loading

wear/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@
33
<string name="voice_text_entry_label">Voice Input</string>
44
<string name="voice_input_label">Voice Text Entry</string>
55
<string name="message_list">Message List</string>
6+
<string name="tile_label">Hello Tile</string>
7+
<string name="tile_description">Hello Tile Description</string>
68
</resources>

0 commit comments

Comments
 (0)