Skip to content

Commit 1b043a4

Browse files
Add example of Lottie animation (#572)
Snippet will be used on https://developer.android.com/training/wearables/tiles/animations.
1 parent b78993d commit 1b043a4

File tree

3 files changed

+307
-0
lines changed

3 files changed

+307
-0
lines changed

wear/src/main/AndroidManifest.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,21 @@
166166
android:resource="@drawable/tile_preview" />
167167
</service>
168168

169+
<service
170+
android:name=".snippets.tile.LottieAnimation"
171+
android:label="@string/tile_label"
172+
android:description="@string/tile_description"
173+
android:icon="@mipmap/ic_launcher"
174+
android:exported="true"
175+
android:permission="com.google.android.wearable.permission.BIND_TILE_PROVIDER">
176+
<intent-filter>
177+
<action android:name="androidx.wear.tiles.action.BIND_TILE_PROVIDER" />
178+
</intent-filter>
179+
180+
<meta-data android:name="androidx.wear.tiles.PREVIEW"
181+
android:resource="@drawable/tile_preview" />
182+
</service>
183+
169184
<activity
170185
android:name=".snippets.alwayson.AlwaysOnActivity"
171186
android:label="0 Stopwatch"

wear/src/main/java/com/example/wear/snippets/tile/Animations.kt

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ import androidx.wear.protolayout.ModifiersBuilders
2828
import androidx.wear.protolayout.ModifiersBuilders.AnimatedVisibility
2929
import androidx.wear.protolayout.ModifiersBuilders.DefaultContentTransitions
3030
import androidx.wear.protolayout.ModifiersBuilders.Modifiers
31+
import androidx.wear.protolayout.ResourceBuilders
32+
import androidx.wear.protolayout.ResourceBuilders.Resources
3133
import androidx.wear.protolayout.TimelineBuilders.Timeline
34+
import androidx.wear.protolayout.TriggerBuilders.createOnVisibleTrigger
3235
import androidx.wear.protolayout.TypeBuilders.FloatProp
3336
import androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters
3437
import androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec
@@ -38,11 +41,15 @@ import androidx.wear.protolayout.material.CircularProgressIndicator
3841
import androidx.wear.protolayout.material.Text
3942
import androidx.wear.protolayout.material.layouts.EdgeContentLayout
4043
import androidx.wear.tiles.RequestBuilders
44+
import androidx.wear.tiles.RequestBuilders.ResourcesRequest
4145
import androidx.wear.tiles.TileBuilders.Tile
4246
import androidx.wear.tiles.TileService
47+
import com.example.wear.R
4348
import com.google.common.util.concurrent.Futures
4449
import com.google.common.util.concurrent.ListenableFuture
4550

51+
// In a real implementation, this needs to change whenever the resources
52+
// change, to ensure the updated resources are loaded.
4653
private const val RESOURCES_VERSION = "1"
4754
private const val someTileText = "Hello"
4855
private val deviceParameters = DeviceParametersBuilders.DeviceParameters.Builder().build()
@@ -310,3 +317,48 @@ class AnimationGeometricTranslation : TileService() {
310317
// [END android_wear_tile_animations_geometric_translation]
311318
}
312319
}
320+
321+
// [START android_wear_tile_animations_lottie]
322+
class LottieAnimation : TileService() {
323+
324+
val lottieResourceId = "lottie_animation"
325+
326+
override fun onTileRequest(requestParams: RequestBuilders.TileRequest): ListenableFuture<Tile> {
327+
328+
val layout =
329+
LayoutElementBuilders.Image.Builder()
330+
.setWidth(dp(150f))
331+
.setHeight(dp(150f))
332+
.setResourceId(lottieResourceId)
333+
.build()
334+
335+
return Futures.immediateFuture(
336+
Tile.Builder()
337+
.setResourcesVersion(RESOURCES_VERSION)
338+
.setTileTimeline(Timeline.fromLayoutElement(layout))
339+
.build()
340+
)
341+
}
342+
343+
override fun onTileResourcesRequest(
344+
requestParams: ResourcesRequest
345+
): ListenableFuture<Resources> {
346+
347+
val lottieImage =
348+
ResourceBuilders.ImageResource.Builder()
349+
.setAndroidLottieResourceByResId(
350+
ResourceBuilders.AndroidLottieResourceByResId.Builder(R.raw.lottie)
351+
.setStartTrigger(createOnVisibleTrigger())
352+
.build()
353+
)
354+
.build()
355+
356+
return Futures.immediateFuture(
357+
Resources.Builder()
358+
.setVersion(requestParams.version)
359+
.addIdToImageMapping(lottieResourceId, lottieImage)
360+
.build()
361+
)
362+
}
363+
}
364+
// [END android_wear_tile_animations_lottie]

wear/src/main/res/raw/lottie.json

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
{
2+
"v": "5.12.2",
3+
"fr": 29.9700012207031,
4+
"ip": 0,
5+
"op": 149.000006068894,
6+
"w": 256,
7+
"h": 256,
8+
"nm": "TestLotties",
9+
"ddd": 0,
10+
"assets": [],
11+
"layers": [
12+
{
13+
"ddd": 0,
14+
"ind": 1,
15+
"ty": 4,
16+
"nm": "Shape Layer 1",
17+
"sr": 1,
18+
"ks": {
19+
"o": {
20+
"a": 0,
21+
"k": 100,
22+
"ix": 11
23+
},
24+
"r": {
25+
"a": 0,
26+
"k": 0,
27+
"ix": 10
28+
},
29+
"p": {
30+
"a": 0,
31+
"k": [128, 128, 0],
32+
"ix": 2,
33+
"l": 2
34+
},
35+
"a": {
36+
"a": 0,
37+
"k": [0, 0, 0],
38+
"ix": 1,
39+
"l": 2
40+
},
41+
"s": {
42+
"a": 0,
43+
"k": [100, 100, 100],
44+
"ix": 6,
45+
"l": 2
46+
}
47+
},
48+
"ao": 0,
49+
"shapes": [
50+
{
51+
"ty": "gr",
52+
"it": [
53+
{
54+
"ty": "rc",
55+
"d": 1,
56+
"s": {
57+
"a": 0,
58+
"k": [147.598, 101.668],
59+
"ix": 2
60+
},
61+
"p": {
62+
"a": 0,
63+
"k": [0, 0],
64+
"ix": 3
65+
},
66+
"r": {
67+
"a": 0,
68+
"k": 0,
69+
"ix": 4
70+
},
71+
"nm": "Rectangle Path 1",
72+
"mn": "ADBE Vector Shape - Rect",
73+
"hd": false
74+
},
75+
{
76+
"ty": "fl",
77+
"c": {
78+
"a": 0,
79+
"k": [0.373262771906, 0.896561446844, 0.9078125, 1],
80+
"ix": 4
81+
},
82+
"o": {
83+
"a": 0,
84+
"k": 100,
85+
"ix": 5
86+
},
87+
"r": 1,
88+
"bm": 0,
89+
"nm": "Fill 1",
90+
"mn": "ADBE Vector Graphic - Fill",
91+
"hd": false
92+
},
93+
{
94+
"ty": "tr",
95+
"p": {
96+
"a": 1,
97+
"k": [
98+
{
99+
"i": {
100+
"x": 0.833,
101+
"y": 0.833
102+
},
103+
"o": {
104+
"x": 0.167,
105+
"y": 0.167
106+
},
107+
"t": 89,
108+
"s": [-3.201, -3.166],
109+
"to": [0, 0],
110+
"ti": [0, 0]
111+
},
112+
{
113+
"t": 118.000004806239,
114+
"s": [-61.201, 57.834]
115+
}
116+
],
117+
"ix": 2
118+
},
119+
"a": {
120+
"a": 1,
121+
"k": [
122+
{
123+
"i": {
124+
"x": 0.833,
125+
"y": 0.833
126+
},
127+
"o": {
128+
"x": 0.167,
129+
"y": 0.167
130+
},
131+
"t": 60,
132+
"s": [26, 10],
133+
"to": [0, 0],
134+
"ti": [0, 0]
135+
},
136+
{
137+
"t": 89.0000036250443,
138+
"s": [1, 45]
139+
}
140+
],
141+
"ix": 1
142+
},
143+
"s": {
144+
"a": 1,
145+
"k": [
146+
{
147+
"i": {
148+
"x": [0.833, 0.833],
149+
"y": [0.833, 0.833]
150+
},
151+
"o": {
152+
"x": [0.167, 0.167],
153+
"y": [0.167, 0.167]
154+
},
155+
"t": 118,
156+
"s": [57, 126]
157+
},
158+
{
159+
"t": 146.000005946702,
160+
"s": [107, 69]
161+
}
162+
],
163+
"ix": 3
164+
},
165+
"r": {
166+
"a": 1,
167+
"k": [
168+
{
169+
"i": {
170+
"x": [0.833],
171+
"y": [0.833]
172+
},
173+
"o": {
174+
"x": [0.167],
175+
"y": [0.167]
176+
},
177+
"t": 28,
178+
"s": [18]
179+
},
180+
{
181+
"t": 60.0000024438501,
182+
"s": [60]
183+
}
184+
],
185+
"ix": 6
186+
},
187+
"o": {
188+
"a": 1,
189+
"k": [
190+
{
191+
"i": {
192+
"x": [0.833],
193+
"y": [0.833]
194+
},
195+
"o": {
196+
"x": [0.167],
197+
"y": [0.167]
198+
},
199+
"t": 0,
200+
"s": [48]
201+
},
202+
{
203+
"t": 28.0000011404634,
204+
"s": [100]
205+
}
206+
],
207+
"ix": 7
208+
},
209+
"sk": {
210+
"a": 0,
211+
"k": 0,
212+
"ix": 4
213+
},
214+
"sa": {
215+
"a": 0,
216+
"k": 0,
217+
"ix": 5
218+
},
219+
"nm": "Transform"
220+
}
221+
],
222+
"nm": "Rectangle 1",
223+
"np": 3,
224+
"cix": 2,
225+
"bm": 0,
226+
"ix": 1,
227+
"mn": "ADBE Vector Group",
228+
"hd": false
229+
}
230+
],
231+
"ip": 0,
232+
"op": 900.000036657751,
233+
"st": 0,
234+
"ct": 1,
235+
"bm": 0
236+
}
237+
],
238+
"markers": [],
239+
"props": {}
240+
}

0 commit comments

Comments
 (0)