BottomNavigationView解决三个限制记录

在查看lottie动画库的代码时发现它的底部是利用BottomNavigationView实现的底部导航栏,但是却不受3个的限制(控件超过三个就会进行处理,隐藏除选中外的文字并缩小),还保留了控件原本3个以内的效果,这里我就把它的代码贴出来

  • BottomNavigationView的结构,清楚了控件的构成就容易解决问题了

//从上倒下包含
BottomNavigationView 
BottomNavigationMenu 
BottomNavigationItemView 复制代码
  • lottie中代码使用kotlin写的

private val TAG = NoShiftBottomNavigationView::class.java.name
​
class NoShiftBottomNavigationView @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyleAttr: Int = 0
) : BottomNavigationView(context, attrs, defStyleAttr) {
​
    override fun onViewAdded(child: View?) {
        super.onViewAdded(child)
        removeShiftAnimation()
    }
​
    @SuppressLint("RestrictedApi")
    private fun removeShiftAnimation() {
        val menuView = getChildAt(0) as BottomNavigationMenuView
        try {
            menuView::class.java.getDeclaredField("mShiftingMode").apply {
                isAccessible = true
                setBoolean(menuView, false)
                isAccessible = false
            }
​
            menuView.children
                    .map { it as BottomNavigationItemView }
                    .forEach {
                        it.setShiftingMode(false)
                        it.setChecked(it.itemData.isChecked)
                    }
        } catch (e: NoSuchFieldException) {
            Log.e(TAG, "Unable to get shift mode field", e)
        } catch (e: IllegalAccessException) {
            Log.e(TAG, "Unable to change value of shift mode", e)
        }
    }
}复制代码
  • 我也写了一份java的(最近正好在学koltin)

public class NoShiftBottomNavigationView extends BottomNavigationView {
​
    private String TAG = getClass().getSimpleName();
    
    public NoShiftBottomNavigationView(Context context) {
        this(context,null);
    }
​
    public NoShiftBottomNavigationView(Context context, AttributeSet attrs) {
        super(context, attrs,0);
    }
​
    public NoShiftBottomNavigationView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
​
    @Override
    public void onViewAdded(View child) {
        super.onViewAdded(child);
        //当底部导航菜单被添加,去除系统的效果
        removeShiftAnimation();
    }
​
    @SuppressLint("RestrictedApi")
    private void removeShiftAnimation() {
        BottomNavigationMenuView menuView = (BottomNavigationMenuView) getChildAt(0);
        try {
            //利用反射获取到mShiftingMode属性,设置为false不需要shift动画效果(控制移动动画)
            Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode");
            //忽略该属性的访问显示
            shiftingMode.setAccessible(true);
            shiftingMode.setBoolean(menuView,false);
            shiftingMode.setAccessible(false);
​
            //取消每一个子菜单的shift动画效果(控制文字是否显示隐藏)
            for (int i = 0; i < menuView.getChildCount(); i++) {
                BottomNavigationItemView itemView  = (BottomNavigationItemView) menuView.getChildAt(i);
                itemView.setShiftingMode(false);
                itemView.setChecked(itemView.getItemData().isChecked());
            }
        } catch (NoSuchFieldException e) {
            Log.e(TAG, "Unable to get shift mode field", e);
        } catch (IllegalAccessException e) {
            Log.e(TAG, "Unable to change value of shift mode", e);
        }
    }
}复制代码
  • 注意

    如果混淆了design包记得忽略混淆该属性,防止混淆后属性名变化,反射无法找到该属性,导致异常

-keepclassmembers class android.support.design.internal.BottomNavigationMenuView { 
    boolean mShiftingMode; 
}复制代码


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值