当使用BottomNavigationView菜单项多于3个时,去除动画效果,显示菜单项文字

问题描述: 我们使用BottomNavigationView作为底部菜单时,当菜单项多于3个时,效果和3个及以下的效果已经完全不一样了,只有选中的菜单项才会显示出文字,未选中的菜单项只显示图标。动画效果看着很炫酷,但是APP设计要求的效果是与菜单项是3个的一致。下面我介绍一种解决的方案,首先看一下未做处理的4个菜单项效果图(图1)和做过处理的效果图(图2):
图1 -----》图2

design:28.0.0 以下版本处理方式

第一步:我之前写过一片文章简单介绍了BottomNavigationView的使用BottomNavigationView+ViewPager实现底部导航栏 ,这篇文章是3个菜单项,在此基础上,我添加了一个“收藏”的菜单项。先来看一下这个菜单栏的控件简单分析:
这里写图片描述
整体使用
BottomNavigationView
,这个不用多说,BottomNavigationView的子view是BottomNavigationMenuView,它包含菜单项构成菜单。每一个菜单项是BottomNavigationItemView。BottomNavigationMenuView和BottomNavigationItemView的关系类似于我们常见的RadioGroup和RadioButton。

问题分析: 我们不关心这个动画是如何实现的,我们的主要目标是如何去掉这个动画,动画效果是在菜单项上,所以我们首先想到,这个动画应该在BottomNavigationMenuView设置中,所以说看BottomNavigationMenuView的源码是必不可少的。源码这么多,我们不可能一步一步看,我们需要通过问题去定位我们想要的代码。我们已经知道,菜单项3个及以下和3个以上的效果完全不同。所以说3是个临界值,在3这个临界值时必须要做判断然后添加或者删除动画。目标已经有了,其实可以迅速可以定位到关键代码,贴一块关键代码:

		private boolean mShiftingMode = true;
		...
		mButtons = new BottomNavigationItemView[mMenu.size()];
        mShiftingMode = mMenu.size() > 3;
        for (int i = 0; i < mMenu.size(); i++) {
            mPresenter.setUpdateSuspended(true);
            mMenu.getItem(i).setCheckable(true);
            mPresenter.setUpdateSuspended(false);
            BottomNavigationItemView child = getNewItem();
            mButtons[i] = child;
            child.setIconTintList(mItemIconTint);
            child.setTextColor(mItemTextColor);
            child.setItemBackground(mItemBackgroundRes);
            child.setShiftingMode(mShiftingMode);
            child.initialize((MenuItemImpl) mMenu.getItem(i), 0);
            child.setItemPosition(i);
            child.setOnClickListener(mOnClickListener);
            addView(child);
        }
        mSelectedItemPosition = Math.min(mMenu.size() - 1, mSelectedItemPosition);
        mMenu.getItem(mSelectedItemPosition).setChecked(true);

判断条件mShiftingMode = mMenu.size() > 3;然后设置动画有与无child.setShiftingMode(mShiftingMode);到这里,我们已经清楚怎么做了,只要设置child.setShiftingMode(false); 无论有多少个菜单项都可以去除动画了。

解决方案: 我本来想继承BottomNavigationView来自定义view来实现设置setShiftingMode(false),搞了好大一会没有达到预期效果。后来在stackoverflow发现采用反射机制来获取菜单项BottomNavigationItemView的对象,然后设置setShiftingMode(false),实现代码如下:

public class BottomNavigationViewHelper {

    public static void disableShiftMode(BottomNavigationView view) {
        //获取子View BottomNavigationMenuView的对象
        BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
        try {
            //设置私有成员变量mShiftingMode可以修改
            Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode");
            shiftingMode.setAccessible(true);
            shiftingMode.setBoolean(menuView, false);
            shiftingMode.setAccessible(false);
            for (int i = 0; i < menuView.getChildCount(); i++) {
                BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
                //去除shift效果
                item.setShiftingMode(false);
                item.setChecked(item.getItemData().isChecked());
            }
        } catch (NoSuchFieldException e) {
            Log.e("BNVHelper", "没有mShiftingMode这个成员变量", e);
        } catch (IllegalAccessException e) {
            Log.e("BNVHelper", "无法修改mShiftingMode的值", e);
        }
    }
}

使用很简单,findViewById找到BottomNavigationView 时直接调用即可

BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
BottomNavigationViewHelper.disableShiftMode(navigation);

design:28.0.0 处理方式

android官方已经处理了这个问题,可以通过直接配置进行设置,只需在布局xml文件中的BottomNavigationView控件下加入下面这一行代码 app:labelVisibilityMode=“labeled” 就行了

<android.support.design.widget.BottomNavigationView
        android:id="@+id/navigation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:background="?android:attr/windowBackground"
        app:labelVisibilityMode="labeled"
        app:menu="@menu/navigation" />

文章这里就结束了,有不对的地方欢迎指正,这里我推荐一个大神写的github的开源代码BottomNavigation,类似于BottomNavigationView,但是比BottomNavigationView炫酷,有兴趣的可以研究研究。

  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
好的,可以使用Matlab来实现这个问题。首先,我们需要收集一些数据,包括人数、车数、上车点数和平均用。假设我们已经有了这些数据,可以按照以下步骤进行操作: 1. 导入数据并计算人多于车的情况下的上车点数和平均用。 2. 绘制散点图来显示上车点数和平均用之间的关系。 3. 在图表上添加趋势线和方程式,以更清楚地显示这种关系。 下面是一些可能的Matlab代码来实现这个问题: ```matlab % 1. 导入数据并计算人多于车的情况下的上车点数和平均用 people = [10 20 30 40 50 60 70 80 90 100]; cars = [5 10 15 20 25 30 35 40 45 50]; boarding_points = [8 14 20 24 26 28 30 32 33 34; 9 16 22 27 30 32 34 35 36 36; 10 18 25 30 33 35 37 38 39 40; 11 20 27 33 36 38 40 41 42 43; 12 22 29 35 38 40 42 43 44 45; 13 24 31 37 40 42 44 45 46 47; 14 26 33 39 42 44 46 47 48 49; 15 28 35 41 44 46 48 49 50 50; 16 30 37 43 46 48 50 50 50 50; 17 32 39 45 48 50 50 50 50 50]; average_times = [8.2 7.7 7.3 7.0 6.8 6.6 6.5 6.4 6.4 6.3; 9.0 8.3 7.9 7.6 7.4 7.2 7.0 6.9 6.9 6.8; 10.0 9.2 8.7 8.3 8.0 7.8 7.6 7.5 7.4 7.4; 11.0 10.0 9.2 8.8 8.5 8.3 8.1 8.0 7.9 7.8; 12.0 11.0 10.0 9.2 8.9 8.6 8.4 8.3 8.2 8.1; 13.0 12.0 11.0 10.0 9.3 9.0 8.7 8.6 8.5 8.4; 14.0 13.0 12.0 11.0 10.0 9.3 9.0 8.8 8.7 8.6; 15.0 14.0 13.0 12.0 11.0 10.0 9.3 9.0 8.9 8.8; 16.0 15.0 14.0 13.0 12.0 11.0 10.0 9.3 9.0 8.9; 17.0 16.0 15.0 14.0 13.0 12.0 11.0 10.0 9.3 9.0]; [row, col] = find(people > cars); boarding_points(row, col) = NaN; average_times(row, col) = NaN; % 2. 绘制散点图来显示上车点数和平均用之间的关系 figure; scatter(boarding_points(:), average_times(:), 'filled'); xlabel('上车点数'); ylabel('平均用'); title('人多于上车点数与人车平均用关系图'); % 3. 在图表上添加趋势线和方程式 hold on; p = polyfit(boarding_points(:), average_times(:), 1); x = linspace(min(boarding_points(:)), max(boarding_points(:))); y = polyval(p, x); plot(x, y, 'r'); text(10, 8, sprintf('y = %.2fx + %.2f', p(1), p(2)), 'Color', 'r'); legend({'数据点', '趋势线'}, 'Location', 'northwest'); hold off; ``` 这些代码将生成一个散点图,显示上车点数和平均用之间的关系,并在图表上添加了趋势线和方程式。你可以根据自己的数据进行调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值