Android 实现可替换的基于lottie动画底部导航栏实践

本文第一部分是实现底部动画导航栏,第二部分是实现动态替换动画文件(点击直达)

 

一、动画导航栏实现

最终效果:

需求描述:

如上图,底部是数量不固定的选项卡,排列方式是剩余空间均分,点击切换tab时,被选中的tab会跟随动画,且展示对应tab的内容

需求拆分:

1. 关于动画,实现方式可以是加载gif文件;也可以采用lottie加载json文件。lottie的优势在于像素加载够清晰,如果lottie遇到加载问题,建议升级lottie库到最新版本。

2. 关于均匀分布,可以采用ConstraintLayout的chainStyle属性为spread实现;也可以使用LinearLayout在每个选项卡之间加入空的space控件,weight都是1,平分剩余空间。

3. 关于tab切换,实现方式有很多种,本文采用自定义view,定制化比较好,其他也可以采用Materail Design的BottomNavigationView或是TabLayout,但是定制需求比较受限,比如一些动画效果及字体样式等等

4.关于tab上方内容的显示,通常是通过切换不同的fragment实现tab切换加载不同的内容

需求实现:

引入需要的库:

implementation 'com.airbnb.android:lottie:3.4.0'
implementation 'com.github.bumptech.glide:glide:3.8.0'

1. 自定义tabItem项

在自定义View之前,先对加载View所需的数据结构进行定义,展示需要的元素有表明一个选项卡的唯一标识,动图资源,静图资源及tab名称,可以定义一个接口去实现它

public interface TabItem {

    String getName();

    @DrawableRes
    int getStaticRes();

    @DrawableRes
    int getAnimateRes();

    String getTabType();
}

自定义View的实现:

public class TabItemView extends FrameLayout {
    private Context mContext;
    private TextView mTabNameView;
    private LottieAnimationView mTabLottieView;
    private String mTabName;
    private int mTabStaticRes;
    private int mTabAnimateRes;
    private boolean isSelected;
    private int mSelectedTextColor;
    private int mUnSelectedTextColor;
    private int mTextSize;
    private int mIconSize;

    public TabItemView(@NonNull Context context) {
        this(context, null);
    }

    public TabItemView(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TabItemView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public TabItemView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        mContext = context;
        TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.TabItemView);
        mTextSize = a.getDimensionPixelSize(R.styleable.TabItemView_textSize, 10);
        mIconSize = a.getDimensionPixelSize(R.styleable.TabItemView_iconSize, 40);
        mSelectedTextColor = a.getColor(R.styleable.TabItemView_selectedTextColor, getResources().getColor(R.color.tab_selected));
        mUnSelectedTextColor = a.getColor(R.styleable.TabItemView_unSelectedTextColor, getResources().getColor(R.color.tab_unselected));
        mTabStaticRes = a.getResourceId(R.styleable.TabItemView_mTabStaticRes, 0);
        mTabAnimateRes = a.getResourceId(R.styleable.TabItemView_mTabAnimateRes, 0);
        mTabName = a.getString(R.styleable.TabItemView_tabName);
        a.recycle();
        init();
    }

    private void init() {
        View view = LayoutInflater.from(mContext).inflate(R.layout.bottom_tab_view_item, this, false);
        mTabNameView = view.findViewById(R.id.tab_name);
        mTabLottieView = view.findViewById(R.id.tab_animation_view);
        addView(view);
    }

    private void setSelectedUI() {
        if (mTabAnimateRes == 0) {
            throw new NullPointerException("animation resource must be not empty");
        } else {
            mTabNameView.setTextColor(mSelectedTextColor);
            mTabLottieView.setAnimation(mTabAnimateRes);
       
  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值