Android: Lottie Animation with dynamic text and custom font issue

1.2k Views Asked by At

I'm trying to dynamically swap a text inside a LottieAnimation in jetpack compose. The lottie file is exported without glyphs

It's working when using the old android view inside a

AndroidView(factory = { context ->
    val view = LottieAnimationView(context).apply {
        setAnimation(R.raw.testing_no_glyphs)
        playAnimation()
        repeatCount = LottieConstants.IterateForever
    }

    val textDel = object : TextDelegate(view) {
        override fun getText(layerName: String?, input: String?): String {
            return when (layerName) {
                "Test234" -> "OtherLettersHere"
                else -> super.getText(layerName, input)
            }
        }
    }

    val fontDel = object : FontAssetDelegate() {
        override fun getFontPath(fontFamily: String?, fontStyle: String?, fontName: String?): String {
            return "fonts/[MyFontInside /assets].ttf"
        }
    }

    view.setTextDelegate(textDel)
    view.setFontAssetDelegate(fontDel)
    return@AndroidView view
})

But I can't find the correct handles in the JetpackCompose version of Lottie to get the same result.

If we export the lottie with glyphs, it's works for the letters in the chars array inside the lottie json. But we want to be able to replace with any letters/symbols, so this isn't a viable solution.

I've noticed in the 5.3.0-SNAPSHOT that a fontMap parameter has been added, but I can't figure out which key to hit with it.

Here is my code:

val dynamicProperties = rememberLottieDynamicProperties(
    rememberLottieDynamicProperty(LottieProperty.TEXT, value = "AaBbCcEeFf", keyPath = arrayOf("Test234"))
)
val composition by rememberLottieComposition(
    spec = LottieCompositionSpec.RawRes(R.raw.testing)
)
val progress by animateLottieCompositionAsState(composition, iterations = LottieConstants.IterateForever)

LottieAnimation(
    composition,
    { progress },
    dynamicProperties = dynamicProperties,
    fontMap = mapOf("fName" to Typeface.createFromAsset(LocalContext.current.assets, "fonts/[MyFontInside /assets].ttf"))
)

It just shows a blank for all the texts inside the Lottie Animation - so this is kinda where i'm stuck.

2

There are 2 best solutions below

0
On BEST ANSWER

After some trial an error I found a way to add the typeface for a specific layer:

val typeface = Typeface.createFromAsset(LocalContext.current.assets, "fonts/[MyFontInside /assets].ttf")

val dynamicProperties = rememberLottieDynamicProperties(
    rememberLottieDynamicProperty(LottieProperty.TEXT, value = "AaBbCcEeFf", keyPath = arrayOf("Test234")),
--> rememberLottieDynamicProperty(LottieProperty.TYPEFACE, value = typeface, keyPath = arrayOf("Test234")),
)

Hence there is no need for the fontMap in my case

0
On

You'll need to use the fontMap field in LottieAnimation. In your Lottie json file you'll need to check what font families it need and provide a mapping to a Typeface

fontMap: The key can be "fName", "fFamily", or "fFamily-fStyle" as specified in your Lottie file.

val customFontFamily = FontFamily(Font(R.font.roboto))
val resolver = LocalFontFamilyResolver.current
val typeface by remember { 

LottieAnimation(
    ...
    fontMap = mapOf(
        "Roboto-Regular" to typeface.value as Typeface
    ),
)

OR

val customFontFamily = FontFamily(Font(R.font.roboto))
val resolver = LocalFontFamilyResolver.current
val typeface by remember { mutableStateOf(resolver.resolve(customFontFamily)) }

val dynamicProperties = rememberLottieDynamicProperties(
    rememberLottieDynamicProperty(
        property = LottieProperty.TYPEFACE,
        value = typeface.value,
        keyPath = arrayOf(
            "**" // or some other key path
        )
    )
)