• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }