本文第一部分是实现底部动画导航栏,第二部分是实现动态替换动画文件(点击直达)
一、动画导航栏实现
最终效果:
需求描述:
如上图,底部是数量不固定的选项卡,排列方式是剩余空间均分,点击切换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);