Cannot render when using LottieDrawable without setting bounds with SOFTWARE rendering
CodeReadOnlyUser opened this issue · comments
Lottie is supported and developed on nights and weekends. Issues from Lottie sponsors will be prioritized.
Describe the bug
When using RenderMode.SOFTWARE
or renderMode not specified. LottieDrawable without setting bounds before resumeAnimation()
cannot be rendered using lottieDrawable.draw(canvas)
on devices with Android version < Oreo (API 26)
When using RenderMode.HARDWARE
or devices with Android version >= Oreo (API 26). LottieDrawable without setting bounds before resumeAnimation()
will be rendered. The bounds will be lottieDrawable.composition.bounds
What version of Lottie did you test this on?
implementation("com.airbnb.android:lottie:6.4.0")
and some older versions.
What version of Android did you test this on?
Android API 23, API 25, API 26, API 32, API 34
Steps To Reproduce
Steps to reproduce the behavior:
Custom drawable with lottie example:
class CustomLottieDrawable(val view: View) : Drawable() {
//constants
private val size = 600
private val lottieAssetName = "Lottie Logo 1.json"
private val lottieDrawable: LottieDrawable = initLottieDrawable()
//keep reference here, or callback will be recycled
private var refreshCallback: Callback? = null
init {
this.bounds = Rect(0, 0, size, size)
//⚠️
//lottieDrawable.bounds = Rect(0, 0, size, size)
lottieDrawable.resumeAnimation()
}
override fun draw(canvas: Canvas) {
lottieDrawable.draw(canvas)
}
override fun setAlpha(alpha: Int) {}
override fun setColorFilter(colorFilter: ColorFilter?) {}
override fun getOpacity(): Int = PixelFormat.TRANSLUCENT
private fun initLottieDrawable(): LottieDrawable {
val lottieDrawable = LottieDrawable()
this.refreshCallback = object : Callback {
override fun invalidateDrawable(who: Drawable) {
view.invalidate()
}
override fun scheduleDrawable(who: Drawable, what: Runnable, `when`: Long) {}
override fun unscheduleDrawable(who: Drawable, what: Runnable) {}
}
lottieDrawable.callback = this.refreshCallback
val result = LottieCompositionFactory.fromAssetSync(view.context, lottieAssetName).value
lottieDrawable.composition = result
lottieDrawable.repeatCount = LottieDrawable.INFINITE
//⚠️
//lottieDrawable.renderMode = RenderMode.HARDWARE
return lottieDrawable
}
}
Then, setting this CustomLottieDrawable as some view's background.
Uncomment any lines with
Additional information:
When debugging using lottieDrawable.toBitmap(,,)
, the bitmap is the correct rendered image. So I am wondering why renderMode and Android version can cause different render result.
Solution
Set lottieDrawable.bounds
before calling lottieDrawable.resumeAnimation()
Screenshots
Nothing visible
This is not surprising because with render mode software, the canvas is backed by a bitmap which inherently has bounds due to the bitmap and there is nothing Lottie can do to render beyond that.
with render mode software
I tested again on devices with Android >= 8.0. If SOFTWARE rendering is manually enabled, nothing is rendered. So the real behavior is LottieDrawable without setting bounds will not be visible in SOFTWARE rendering mode.
And the reason why HARDWARE rendering is used starting from Android Oreo can be found here.
Thanks for your answer🙏
@CodeReadOnlyUser It not being visible doesn't sound right. Can you create a project that repros this?