Introduction.gif
animation.gif
使用準備
Lottie支持多平臺,使用同一個JSON動畫文件,可在不同平臺實現相同的效果。Android 通過Airbnb的開源項目lottie-android實現,最低支持 API 16;
在項目的 build.gradle 文件添加依賴
dependencies {
implementation 'com.airbnb.android:lottie:$lottieVersion'
}
最新的版本號可以到官網或者github查詢,lottie僅支持api16及以上。
加載方式
1. src/main/assets
lottieAnimationView = findViewById(R.id.lottieAnimationView);
lottieAnimationView.setImageAssetsFolder("images");
lottieAnimationView.setAnimation("data.json");
lottieAnimationView.loop(true);
lottieAnimationView.playAnimation();
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/lottieAnimationView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:lottie_fileName="hello-world.json"
app:lottie_loop="true"
app:lottie_autoPlay="true" />
2. Json String
加載服務器上的.json文件,若有圖片可以設置本地代理文件夾或者將圖片資源放入 JSON。
private void loadUrl(String url) {
Request request = new Request.Builder().url(url).build();
OkHttpClient client = new OkHttpClient();
client.newCall(request).enqueue(new Callback() {
@Override public void onFailure(Call call, IOException e) {}
@Override public void onResponse(Call call, Response response) throws IOException {
try {
JSONObject json = new JSONObject(response.body().string());
LottieComposition.Factory
.fromJson(getResources(), json, new OnCompositionLoadedListener() {
@Override
public void onCompositionLoaded(LottieComposition composition) {
lottieAnimationView.setComposition(composition);
lottieAnimationView.playAnimation();
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
3. Url 服務器上的壓縮包(包含images和json文件)
- 通過url直接加載
lottieAnimationView.setAnimationFromUrl(url);
lottieAnimationView.playAnimation();
- 下載到本地解壓后指定文件夾代理
// 資源zip
public final static File LOTTIE_FILES = new File(Environment.getExternalStorageDirectory()+"/ctclient/lottie/lottie.zip");
// 動效圖片資源
public final static File IMAGES_FILES = new File(Environment.getExternalStorageDirectory()+"/ctclient/lottie/images");
// data.json路徑
public final static File JSON_FILE = new File(Environment.getExternalStorageDirectory()+"/ctclient/lottie/data.json");
FileInputStream fis = null;
if (JSON_FILE.exists()) {
try {
fis = new FileInputStream(JSON_FILE);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
if (fis == null || !IMAGES_FILES.exists()) {
Log.i("huangssh", "動畫資源不存在");
return;
}
final String absolutePath = IMAGES_FILES.getAbsolutePath();
// 開啟硬件加速
lottieAnimationView.useHardwareAcceleration(true);
// 設置動畫文件夾代理類
lottieAnimationView.setImageAssetDelegate(new ImageAssetDelegate() {
@Override
public Bitmap fetchBitmap(LottieImageAsset asset) {
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inScaled = true;
opts.inDensity = UtilPhoneParam.densityDpi;
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeFile(absolutePath + File.separator + asset.getFileName(), opts);
}catch (Exception e){
e.printStackTrace();
}
return bitmap;
}
});
// 設置動畫
LottieComposition.Factory.fromInputStream(fis, new OnCompositionLoadedListener() {
@Override
public void onCompositionLoaded(@Nullable LottieComposition composition) {
lottieAnimationView.setComposition(composition);
lottieAnimationView.playAnimation();
}
});
4. 加載SDCard字體
lottieAnimationView.setFontAssetDelegate(new FontAssetDelegate(){
public Typeface fetchFont(String fontFamily) {
Typeface customFont = Typeface.createFromFile(FONT_PATH + fontFamily);
return customFont;
}
});
常用方法
1. 監聽動畫進度 [0,1]
lottieAnimationView.addAnimatorUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
// 判斷動畫加載結束
if (valueAnimator.getAnimatedFraction() == 1f) {
if (dialog.isShowing() && getActivity() != null)
dialog.dismiss();
}
}
});
2. 暫停/取消/播放
lottieAnimationView.pauseAnimation();
lottieAnimationView.cancelAnimation();
lottieAnimationView.playAnimation();
3. 循環/播放某個部分
lottieAnimationView.loop(true);
- 像
ValueAnimator
一樣使用setRepeatMode(...)
或setRepeatCount(...)
- scaleType :只支持
centerCrop
和centerInside
- 播放動畫的某個部分
setMinFrame(...)
setMaxFrame(...)
setMinProgress(...)
setMaxProgress(...)
setMinAndMaxFrame(...)
setMinAndMaxProgress(...)
4. 硬件加速,解決lottie卡頓問題
lottieAnimationView.useHardwareAcceleration(true);
5. 緩存
/*
* Lottie內部有兩個緩存map(強引用緩存,弱引用緩存),在動畫文件加載完成后會根據設置的緩存策略緩存動畫,方便下次使用。
*/
lottieAnimationView.setAnimation(animation, LottieAnimationView.CacheStrategy.Strong); //強緩存
lottieAnimationView.setAnimation(animation, LottieAnimationView.CacheStrategy.Weak); //弱緩存
根據進度緩存,并為下次播放作準備
lottieAnimationView.setProgress(progress); //設置當前進度
lottieAnimationView.buildDrawingCache(); //強制緩存繪制數據
Bitmap image = lottieAnimationView.getDrawingCache(); //獲取當前繪制數據
After Effects方面注意點(for設計師)
1. 官網動畫實例 www.lottiefiles.com
2. AE文件預覽 https://www.lottiefiles.com/preview
3. 在為Lottie構建時,您始終必須記住,這些JSON文件需要盡可能小巧令移動產品盡可能小。 例如,盡可能使用parenting。 在類似的圖層上復制相同的關鍵幀會增加額外的代碼。 只有在必要時才使用路徑關鍵幀動畫。 由于它為每個關鍵幀上的每個頂點添加數據,因此占用的空間最多。 諸如Autotrace之類的技術,或者每幀都為您提供關鍵幀的搖擺器,可能會使您的JSON文件非常大,并可能會對性能產生負面影響。 必須與組合物的設置方式保持平衡,以使事物盡可能高效。
4. 將任何Adobe Illustrator,EPS,SVG或PDF資源轉換為After Effects中的圖層,否則它們將無法在您的Lottie動畫中使用。
5. Lottie尚不支持效果菜單中的表達式或任何效果。
6. 使用alpha遮罩會影響性能。 如果你使用的是alpha遮罩或alpha倒置遮罩,遮罩的大小會對性能產生更大的影響。 如果必須使用遮罩,請覆蓋最小的區域。
7. 混合模式(如Multiply, Screen 或 Add)尚不受支持,也不支持Luma遮罩。
8. Lottie還不支持陰影,顏色疊加或筆觸等圖層效果。
9. 導出比您想要支持的最寬屏幕更寬的動畫,使開發者在Android上使用centerCrop類型或在iOS上使用aspectFill內容模式。
10. 將圖片資源放入JSON, 將圖片資源整合到動畫的 JSON文件中,開發人員的工作量就可以節約很多。
- 需要先將圖片轉換成矢量圖 SVG 格式,這個設計師一定有辦法。
- 使用 Illustrator 將 SVG 文件另存為 .ai 文件。
- 使用 .ai 文件在 AE 中做動畫處理。
- 最后通過 Bodymovin 插件,輸出動畫資源。
官方文檔: artwork-to-lottie-walkthrough