Android(安卓)带Lottie动画的导航栏
16lz
2021-01-24
-
什么是Lottie动画
Lottie 是Airbnb开源的一个面向 iOS、Android、React Native 的动画库,能分析 Adobe After Effects 导出的动画,并且能让原生 App 像使用静态素材一样使用这些动画,完美实现动画效果,动画效果比原生动画要优美很多。Lottie动画由UI提供,UI给到我们的是xxx.json文件,这个文件就是动画文件。
优点:动画效果好,灵活,导入方便,使用简单,可以从网络下载,支持多平台。
缺点:性能没有属性动画好。 -
导入Lottie动画库
github地址
在app build.gradle 中导入
implementation 'com.airbnb.android:lottie:$lottieVersion'
$lottieVersion 为版本号。
注意2.8.0及之后的版本加入了android x, 如果你的项目没有使用android x ,要使用2.8.0之前的版本,否则会编译失败
Lottie 2.8.0 and above only supports projects that have been migrated
to androidx.
- 导入动画文件
在 main文件夹下创建assets文件夹,将json文件放入assets文件夹下。需要确认json中是否包含本地文件路径,例如 img0/image1.png,如果存在,需要将本地图片按路径存储,否则运行会报错。
- 代码中实现动画播放
关键类 LottieAnimationView ,LottieDrawable 。此类实现Lottie动画的配置及控制。
LottieAnimationView继承AppCompatImageView,所以它是支持Lottie的Imageview。
mLottieView.setImageAssetsFolder("image0"); //设置本地文件路径mLottieView.setRepeatCount(0); //设置重复次数,默认0mLottieView.setAnimation(mAnimationPath);//mAnimationPath 是动画json文件的相对路径mLottieView.playAnimation();//播放动画 //其他属性自行搜索
以上配置也可以在xml中配置。
app:lottie_fileName="xxx.json"app:lottie_repeatCount="0"app:lottie_imageAssetsFolder="image0"//其他属性自行搜索
- 导航栏实现
新建自定义控件 LottieTabView
public class LottieTabView extends FrameLayout { private int mTextNormalColor; private int mTextSelectColor; private float mTextSize; private String mTabName; private Drawable mIconNormal; private String mAnimationPath; private LottieAnimationView mLottieView; private TextView mTabNameView; private TextView mMsgView; private boolean isSelected; public LottieTabView(Context context) { super(context); } public LottieTabView(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } public LottieTabView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context, attrs); } private void init(Context context, AttributeSet attrs) { TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.LottieTabView); mTextNormalColor = ta.getColor(R.styleable.LottieTabView_text_normal_color, Color.BLACK); mTextSelectColor = ta.getColor(R.styleable.LottieTabView_text_selected_color, Color.BLUE); mTextSize = ta.getDimension(R.styleable.LottieTabView_text_size, SizeUtils.dp2px(5)); mIconNormal = ta.getDrawable(R.styleable.LottieTabView_icon_normal); mAnimationPath = ta.getString(R.styleable.LottieTabView_lottie_path); mTabName = ta.getString(R.styleable.LottieTabView_tab_name); isSelected = ta.getBoolean(R.styleable.LottieTabView_tab_selected, false); ta.recycle(); initView(context); } private void initView(Context context) { View containView = LayoutInflater.from(context).inflate(R.layout.lottie_tab_view, null, false); mLottieView = containView.findViewById(R.id.animation_view); mLottieView.setRepeatCount(0); mTabNameView = containView.findViewById(R.id.tab_name); mTabNameView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize); mTabNameView.setTextColor(mTextNormalColor); mTabNameView.setText(mTabName); mMsgView = containView.findViewById(R.id.msg_view); this.addView(containView); if (isSelected) { selected(); } else { unSelected(); } } public void selected() { if (TextUtils.isEmpty(mAnimationPath)) { throw new NullPointerException("ainmation path must be not empty"); } else { mLottieView.setAnimation(mAnimationPath); mLottieView.playAnimation(); mTabNameView.setTextColor(mTextSelectColor); } } public void unSelected() { mTabNameView.setTextColor(mTextNormalColor); mLottieView.clearAnimation(); mLottieView.setImageDrawable(mIconNormal); }//在右上角显示消息提示数量 public void showMsg(int num) { if (num > 0 && num <= 99) { mMsgView.setVisibility(VISIBLE); mMsgView.setText(num + ""); } else if (num > 99) { mMsgView.setVisibility(VISIBLE); mMsgView.setText("99+"); } else { mMsgView.setVisibility(View.GONE); } }
控件布局文件
<?xml version="1.0" encoding="utf-8"?>
attr.xml中
界面中使用
Mainactivity中
@OnClick({R.id.tab_view_main, R.id.tab_view_msg, R.id.tab_view_deal, R.id.tab_view_mine}) public void onClickView(View view) { switch (view.getId()) { case R.id.tab_view_main: displayFragment(0);//展示相应的fragment mLottieMainTab.selected(); mLottieMsgTab.unSelected(); mLottieDealTab.unSelected(); mLottieMineTab.unSelected(); break; case R.id.tab_view_msg: displayFragment(1); mLottieMsgTab.selected(); mLottieDealTab.unSelected(); mLottieMineTab.unSelected(); mLottieMainTab.unSelected(); break; case R.id.tab_view_deal: displayFragment(2); mLottieDealTab.selected(); mLottieMsgTab.unSelected(); mLottieMineTab.unSelected(); mLottieMainTab.unSelected(); break; case R.id.tab_view_mine: displayFragment(3); mLottieMineTab.selected(); mLottieMsgTab.unSelected(); mLottieDealTab.unSelected(); mLottieMainTab.unSelected(); break; } }
待优化:在此基础上再封装一层LottieTabLayout,动态设置每个LottieTabView的属性。在MainActivity 中直接使用LottieTabLayout。
- 效果
视频录制有些卡顿,现实没有问题。
所需资源
End
更多相关文章
- ADB适用方法
- Android(安卓)APK自动化测试
- app launcher 名称不是清单文件中的android:label
- android监听文件和目录的创建删除移动等事件
- sdcard
- 安卓(android)开发框架的说明1:基于Eclipse的安卓工程开发目录介绍
- Android系统下的动态Dex加载
- Android测试教程(3):测试项目
- 让你的Android开发效率提高10倍的开源工具库AndroidTools的使用