- PVSM.RU - https://www.pvsm.ru -
Привет!
В свое время Product Owner попросил подумать нас о создании эффективного процесса по внедрению анимации в наше приложение на android/ios. В то время мы делали задачу по предзаполнению заявки личными данными на кредитный продукт, и на ответ от сервера требовалось некоторое время, во время которого мы хотели показывать красивую анимацию загрузки.

Задача была понятна: дизайнер хотел нарисовать красиво, отдать исходники сразу на обе
платформы без допиливаний с его стороны, и чтобы это все не лагало на старых устройствах (да, мы ещё поддерживаем android 4.1).
Какие у меня были варианты для внедрения анимации:
Покопав некоторое время в сторону нативной векторной анимации андроида и gif (о боже, мы все-таки рассматривали этот вариант), я вспомнил про замечательную библиотеку Lottie, и показал её коллегам.
После некоторых проведенных тестов с различными девайсами мы решили, что библиотеку надо внедрять, тем более, что ее возможности впечатляли. Особенно обрадовался дизайнер, теперь он мог делать практически любую анимацию в Adobe After Effects, и экспортировать в json файл несколькими кликами. Обрадовались и мы, но обо всем по порядку.
Lottie была придумана и реализована компанией Airbnb в ответ на растущий запрос в кроссплатформенной анимации, поэтому она одинаково (ну почти) работает на всех платформах. Сами разработчики утверждают, что их цель — реализовать максимальное количество функций After Effects, и в этом они преуспели. Сейчас внедрить Lottie анимацию так же просто, как и вставить картинку в ImageView.
Ключевых 3 класса:
Поддерживается загрузка ресурсов из:
Классно то, что все анимации, загруженные через res/raw или assets, сохраняются LRU кэшем, что позволяет не тратить попусту пользовательское время повторно на загрузку и парсинг анимации, так как в случае сложной анимации может потребоваться какое-то время. Что ещё круче, если вам нужно предварительно загрузить анимацию, а потом в следующем фрагменте отобразить анимацию мгновенно, вы можете воспользоваться кодом
LottieCompositionFactory.fromRawRes(context, rawFile)
Анимация закэшируется по ключу rawFile, и там, где вам нужно её будет реально использовать, она запустится почти мгновенно.
Lottie позволяет устанавливать текущее состояние анимации через setProgress(...). Это может пригодиться, если вы хотите анимировать состояние загрузки файла, позиции скролла, различных жестах и т.д. Я видел различные реализации на BottomSheets, PullToRefresh, CollapsingToolbarLayout.
Вот как можно использовать прогресс с AppBarLayout:
appBarLayout.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener
{ appBarLayout, verticalOffset ->
val percent = Math.abs(verticalOffset).toFloat()/appBarLayout.totalScrollRange
animationView.progress = percent
})
Lottie поддерживает циклическое воспроизведение setRepeatMode() или setRepeatCount() не только целой анимации, но и любого фрагмента в пределах (0.0...1.0). Это реализуется свойствами setMinFrame, setMaxFrame, setMinAndMaxFrame. Мы использовали это, чтобы не реализовывать 3 анимации для разных состояний загрузки файла: idle, progress, complete. Вот небольшой кусочек кода, который это решает:
when (loadingStatus) {
LoadingStatus.IDLE -> {
animationView.setMaxProgress(0.1f)
}
LoadingStatus.PROGRESS -> {
animationView.setMinAndMaxProgress(0.2f, 0.9f)
animationView.repeatCount = LottieDrawable.INFINITE
animationView.playAnimation()
}
LoadingStatus.COMPLETE -> {
animationView.setMinAndMaxProgress(0.9f, 1f)
animationView.repeatCount = 1
animationView.playAnimation()
}}

Одним из главных достоинств Lottie для нас стало то, что библиотека поддерживает вставку картинок прямо в анимацию. Причем, вы можете вставить как статичную картинку, так и динамическую, скачанную из интернета. Сейчас объясню как это работает.
В случае со статической картинкой все просто: дизайнер выгружает вам архив, где содержится json плюс сама картинка.
{
"v": "5.1.13",
"fr": 29.9700012207031,
"ip": 0,
"op": 47.0000019143492,
"w": 1034,
"h": 1334,
"nm": "Композиция 1",
"ddd": 0,
"assets": [
{
"id": "image_0",
"w": 130,
"h": 436,
"u": "images/",
"p": "img_0.png"
},
{
"id": "comp_0",
"layers": [
...
]}]
}
Вот этот img_0.png, это и есть картинка, которую вы должны положить в src/assets, и которая будет внутри анимации.
При динамической загрузке используется метод setImageAssetDelegate, в который вы должны передать bitmap. Мы предварительно загружаем картинку Glide-ом, поэтому на этапе открытия фрагмента с анимацией и картинкой все достается из кэша, поэтому всё довольно быстро. Вот код:
glideLoader.loadAsBitmap(imageUrl).into(object: CustomTarget<Bitmap>() {
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
viewAnimation.setImageAssetDelegate(object: ImageAssetDelegate {
override fun fetchBitmap(asset: LottieImageAsset?): Bitmap {
asset?.let {
val resizeBitmap =Bitmap.createScaledBitmap(resource, it.width, it.height, true);
return resizeBitmap
} ?: run {
return resource
}
}
})
setAnimation(viewAnimation, animationImage)
}
override fun onLoadCleared(placeholder: Drawable?) {}
})

Конечно, лучше не использовать много анимации на экранах, где пользователь проводит много времени, так как она требовательна к процессору. По нашим тестам, загрузка процессора на некоторых анимациях доходит до 20%. Поэтому идеальный кейс такой анимации — это интерактивные элементы, которые срабатывают один раз.
Если анимация на некоторых устройствах подтормаживает, иногда помогает
viewAnimation.useHardwareAcceleration(true)
Однако разработчики рекомендуют использовать этот метод с осторожностью, так как разные телефоны по разному используют аппаратное ускорение, поэтому вместо ускорения вы можете получить обратный эффект.
В целом, использование библиотеки Lottie существенно упрощает внедрение анимации в приложение.
Основные плюсы lottie, которые мы выделили:
Минусы:

Кстати, чтобы проверить насколько ресурсоемка анимация, можно воспользоваться официальным приложением Lottie из Google Play [1]. Там есть Render Graph, где вы можете увидеть время на рендеринг кадра, а также посмотреть, как будет выглядеть анимация, если разрезать её по кадрам, или как повлияет hardwareAcceleration и многое другое.
Автор: vernau
Источник [2]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/android-development/323816
Ссылки в тексте:
[1] Lottie из Google Play: https://play.google.com/store/apps/details?id=com.airbnb.lottie
[2] Источник: https://habr.com/ru/post/459852/?utm_source=habrahabr&utm_medium=rss&utm_campaign=459852
Нажмите здесь для печати.