1 package com.airbnb.lottie.sample.compose.examples
2
3 import android.content.Context
4 import android.graphics.Bitmap
5 import android.graphics.BitmapFactory
6 import androidx.compose.foundation.layout.Column
7 import androidx.compose.foundation.layout.fillMaxWidth
8 import androidx.compose.foundation.rememberScrollState
9 import androidx.compose.foundation.verticalScroll
10 import androidx.compose.runtime.Composable
11 import androidx.compose.runtime.LaunchedEffect
12 import androidx.compose.runtime.derivedStateOf
13 import androidx.compose.runtime.getValue
14 import androidx.compose.runtime.mutableStateOf
15 import androidx.compose.runtime.remember
16 import androidx.compose.runtime.setValue
17 import androidx.compose.ui.Modifier
18 import androidx.compose.ui.platform.LocalContext
19 import com.airbnb.lottie.LottieProperty
20 import com.airbnb.lottie.compose.LottieAnimation
21 import com.airbnb.lottie.compose.LottieCompositionSpec
22 import com.airbnb.lottie.compose.LottieConstants
23 import com.airbnb.lottie.compose.rememberLottieComposition
24 import com.airbnb.lottie.compose.rememberLottieDynamicProperties
25 import com.airbnb.lottie.compose.rememberLottieDynamicProperty
26 import com.airbnb.lottie.sample.compose.R
27 import kotlinx.coroutines.Dispatchers
28 import kotlinx.coroutines.withContext
29
30 @Composable
ImagesExamplesPagenull31 fun ImagesExamplesPage() {
32 UsageExamplePageScaffold {
33 Column(
34 modifier = Modifier
35 .fillMaxWidth()
36 .verticalScroll(rememberScrollState())
37 ) {
38 ExampleCard("Inline Image", "base64 image embedded in json file") {
39 InlineImage()
40 }
41 ExampleCard("Assets Image", "Image stored in assets") {
42 ImageAssets()
43 }
44 ExampleCard("Dynamic Properties", "Replace an image with dynamic properties") {
45 DynamicProperties()
46 }
47 ExampleCard("Store on LottieImageAsset", "Store the bitmap within LottieImageAsset") {
48 StoredOnImageAsset()
49 }
50 }
51 }
52 }
53
54 @Composable
InlineImagenull55 fun InlineImage() {
56 // Don't cache the composition so the bitmaps can get released once the animation is no longer being used.
57 val composition by rememberLottieComposition(
58 LottieCompositionSpec.RawRes(R.raw.we_accept_inline_image),
59 cacheKey = null,
60 )
61 LottieAnimation(
62 composition,
63 iterations = LottieConstants.IterateForever,
64 )
65 }
66
67 @Composable
ImageAssetsnull68 fun ImageAssets() {
69 // Don't cache the composition so the bitmaps can get released once the animation is no longer being used.
70 val composition by rememberLottieComposition(
71 LottieCompositionSpec.RawRes(R.raw.we_accept),
72 cacheKey = null,
73 imageAssetsFolder = "Images/WeAccept",
74 )
75 LottieAnimation(
76 composition,
77 iterations = LottieConstants.IterateForever,
78
79 )
80 }
81
82 @Composable
DynamicPropertiesnull83 fun DynamicProperties() {
84 // Don't cache the composition so the bitmaps can get released once the animation is no longer being used.
85 val composition by rememberLottieComposition(
86 LottieCompositionSpec.RawRes(R.raw.we_accept),
87 cacheKey = null,
88 )
89 val bitmap = rememberBitmapFromAssets("Images/android.png")
90
91 val dynamicProperties = rememberLottieDynamicProperties(
92 rememberLottieDynamicProperty(LottieProperty.IMAGE, bitmap, "weaccept.jpg")
93 )
94
95 LottieAnimation(
96 composition,
97 iterations = LottieConstants.IterateForever,
98 dynamicProperties = dynamicProperties,
99 )
100 }
101
102 @Composable
StoredOnImageAssetnull103 fun StoredOnImageAsset() {
104 // Don't cache the composition so the bitmaps can get released once the animation is no longer being used.
105 val composition by rememberLottieComposition(
106 LottieCompositionSpec.RawRes(R.raw.we_accept),
107 cacheKey = null,
108 )
109 val imageAsset by remember { derivedStateOf { composition?.images?.get("image_0") } }
110 val bitmap = rememberBitmapFromAssets("Images/android.png")
111 LaunchedEffect(imageAsset, bitmap) {
112 if (imageAsset != null && bitmap != null) {
113 // this stores the bitmap on the original composition's image asset which means that it
114 // will affect *all* LottieAnimation composables that are rendering this LottieComposition.
115 // Use with caution.
116 imageAsset?.bitmap = bitmap
117 }
118 }
119 LottieAnimation(
120 composition,
121 iterations = LottieConstants.IterateForever,
122 )
123 }
124
125 @Composable
rememberBitmapFromAssetsnull126 private fun rememberBitmapFromAssets(asset: String): Bitmap? {
127 var bitmap: Bitmap? by remember { mutableStateOf(null) }
128 val context = LocalContext.current
129 LaunchedEffect(asset) {
130 withContext(Dispatchers.IO) {
131 bitmap = loadBitmapFromAssets(context, asset)
132 }
133 }
134 return bitmap
135 }
136
loadBitmapFromAssetsnull137 private fun loadBitmapFromAssets(context: Context, asset: String?): Bitmap? {
138 asset ?: return null
139 return try {
140 val inputSteam = context.assets.open(asset)
141 val opts = BitmapFactory.Options()
142 opts.inScaled = true
143 opts.inDensity = 1606
144 BitmapFactory.decodeStream(inputSteam, null, opts)
145 } catch (e: Exception) {
146 null
147 }
148 }