airbnb / lottie-android

Render After Effects animations natively on Android and iOS, Web, and React Native
http://airbnb.io/lottie/
Apache License 2.0
34.95k stars 5.4k forks source link

How to load lottie file from internal storage (compose) #2466

Closed ThangnnVMO closed 6 months ago

ThangnnVMO commented 6 months ago

My code :

val bodyResult = rememberLottieComposition(
            spec = LottieCompositionSpec.File(file.path)
        )
        LottieAnimation(
            composition = bodyResult.value,
            modifier = Modifier.size(300.dp)
        )

I want to display lottie file in internal storage. I have tried many ways but nothing work. Please help me!

Lottie version:

    implementation "com.airbnb.android:lottie:4.2.0"
    implementation 'com.airbnb.android:lottie-compose:4.2.0'
gpeal commented 6 months ago

You'll likely want to use the MediaStore APIs or start a document picker intent and get the result as a Uri then use LottieCompositionSpec.ContentProvider with a uri.

I just did a very quick and dirty test that loads an animation from downloads and it worked.

class ComposeIssueReproActivity : AppCompatActivity() {
    private val fileUri = mutableStateOf<Uri?>(null)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val uri = fileUri.value
            if (uri == null) {
                Box(
                    modifier = Modifier
                        .fillMaxSize()
                        .clickable {
                            val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
                                addCategory(Intent.CATEGORY_OPENABLE)
                                type = "*/*" // Specify the MIME type you want to select
                            }
                            @Suppress("DEPRECATION")
                            startActivityForResult(intent, 123)
                        }
                )
            } else {
                Content(fileUri.value)
            }
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == 123 && resultCode == Activity.RESULT_OK) {
            data?.data?.let { uri ->
                fileUri.value = uri
            }
        }
    }

    @Composable
    fun Content(uri: Uri?) {
        uri ?: return
        val composition by rememberLottieComposition(LottieCompositionSpec.ContentProvider(uri))
        val progress by animateLottieCompositionAsState(composition, iterations = LottieConstants.IterateForever)
        LottieAnimation(composition, { progress })
    }
}
ThangnnVMO commented 6 months ago

Thanks for your answer. I found out LottieCompositionSpec.File(file.path) work with only .json files but not .lottie files.