【安卓开发——BottomNavigationView实现底部导航栏】

要添加底部导航栏,可以使用AS自带的BottomNavigationView来实现,方式就是选择Activity,找到BottomNavigationActivity,这样直接改代码方便实现。

因为是导航,所以还需要有具体的页面,这里是activity,将导航页面布局文件大概处理成如下,同理,导航菜单也需要修改,在此略过不讲。

    <!--内容具体的布局容器,以供加载页面-->
    <FrameLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">

    </FrameLayout>

    <!--导航选择,以供选择加载页面-->
    <android.support.design.widget.BottomNavigationView
        android:id="@+id/navigation"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="0dp"
        android:layout_marginStart="0dp"
        android:background="?android:attr/windowBackground"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:menu="@menu/navigation" />

具体的页面就需要fragment来实现了,在此添加几个fragment,添加方式跟fragment类似,下面是项目添加fragment后,在此activity里面添加变量引用

    private FragmentDeviceTab deviceTab;
    private FragmentHomeTab homeTab;
    private FragmentMonitorTab monitorTab;
    private FragmentOrderTab orderTab;
    private FragmentNotificationTab notificationTab;

    //记录当前正在使用的fragment
    private Fragment isFragment;

修改mOnNavigationItemSelectedListener实现,我们要根据不同的fragment加载不同的页面

 private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
            = new BottomNavigationView.OnNavigationItemSelectedListener() {

        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            switch (item.getItemId()) {
                case R.id.navigation_home:
                    if (homeTab == null) {
                        homeTab = new FragmentHomeTab();
                    }
                    switchContent(isFragment, homeTab);
                    return true;
                case R.id.navigation_device:
                    if (deviceTab == null) {
                        deviceTab = new FragmentDeviceTab();
                    }
                    switchContent(isFragment, deviceTab);
                    return true;
                case R.id.navigation_monitor:
                    if (monitorTab == null) {
                        monitorTab = new FragmentMonitorTab();
                    }
                    switchContent(isFragment, monitorTab);
                    return true;
                case R.id.navigation_order:
                    if (orderTab == null) {
                        orderTab = new FragmentOrderTab();
                    }
                    switchContent(isFragment, orderTab);
                    return true;
                case R.id.navigation_notifications:
                    if (notificationTab == null) {
                        notificationTab = new FragmentNotificationTab();
                    }
                    switchContent(isFragment, notificationTab);
                    return true;
            }
            return false;
        }
  };

  public void switchContent(Fragment from, Fragment to) {
        if (isFragment != to) {
            isFragment = to;
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            if (!to.isAdded()) {    // 先判断是否被add过
                ft.hide(from).add(R.id.container, to).commit(); // 隐藏当前的fragment,add下一个到Activity中
            } else {
                ft.hide(from).show(to).commit(); // 隐藏当前的fragment,显示下一个
            }
        }
  }

然后更改初始化代码如下

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化Fragment及底部导航栏,判断activity是否重建,如果不是,则不需要重新建立fragment.
        if (savedInstanceState == null) {
            FragmentTransaction beginTransaction = getFragmentManager().beginTransaction();
            if (homeTab == null) {
                homeTab = new FragmentHomeTab();
            }
            isFragment = homeTab;
            beginTransaction.replace(R.id.container, homeTab).commit();
        }
        BottomNavigationView navigation = (BottomNavigationView)findViewById(R.id.navigation);
        navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
    }

至此,底部导航即实现了。不过当导航菜单超过3个时,效果和3个及以下的效果已经完全不一样了,只有选中的菜单项才会显示出文字,未选中的菜单项只显示图标,如果要去掉此效果,这时需要使用此方法

@SuppressLint("RestrictedApi")
    public static void disableShiftMode(BottomNavigationView view) {
        //Acquisition child View BottomNavigationMenuView Objects
        BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
        try {
            //Setting private member variables mShiftingMode Can be modified
            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);
                //noinspection RestrictedApi
                item.setShiftingMode(false);
                // set once again checked value, so view will be updated
                //noinspection RestrictedApi
                item.setChecked(item.getItemData().isChecked());
            }
        } catch (NoSuchFieldException e) {
            Log.e("BNVHelper", "Unable to get shift mode field", e);
        } catch (IllegalAccessException e) {
            Log.e("BNVHelper", "Unable to change value of shift mode", e);
        }
    }

不过当依赖库 'com.android.support:appcompat-v7:X.0.0-rc02' 中大于等于28时,则应该用以下disableShiftMode方法

    @SuppressLint("RestrictedApi")
    public static void disableShiftMode(BottomNavigationView view) {
        BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
        menuView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);
        menuView.buildMenuView();
    }

另外,如果想要在导航栏添加消息提示角标,实现思路是将一个文本控件的背景设为红色圆圈,然后文本为消息数,最后将此控件附加到导航菜单项上,在onCreate方法里添加代码如下

        //获取整个的NavigationView
        BottomNavigationMenuView menuView = (BottomNavigationMenuView) navigation.getChildAt(0);

        //这里就是获取所添加的每一个Tab(或者叫menu),
        View tab = menuView.getChildAt(3);
        BottomNavigationItemView itemView = (BottomNavigationItemView) tab;

        //加载我们的角标View,新创建的一个布局
        View badge = LayoutInflater.from(this).inflate(R.layout.menu_badge, menuView, false);

        //添加到Tab上
        itemView.addView(badge);
        TextView textView = badge.findViewById(R.id.tv_msg_count);
        textView.setText(String.valueOf(1));
        //无消息时可以将它隐藏即可
        textView.setVisibility(View.VISIBLE);

布局文件如下,里面的background为圆形背景图片

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_msg_count"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginStart="@dimen/dp_10"
        android:layout_marginEnd="@dimen/dp_3"
        android:background="@drawable/bg_red_circle_10"
        android:gravity="center"
        android:textColor="@color/White"
        android:textSize="@dimen/sp_12"
        android:visibility="gone" />

</LinearLayout>

如果要设置按钮选中状态效果,需要设置两个菜单背景图标,一个选择一个未选中状态。在drawable选中,右击→new →Drawable Resources file新增xml资源文件,然后再图标引用处的background设为此xml文件名称。

至此,底部导航实现,去掉原生动画效果,导航栏的消息提示都设计到了,下面放上效果图

其他对底部导航的设置

设置图片和文件件的距离,直接values资源文件夹下面的在dimens中设置:

<dimen tools:override="true" name="design_bottom_navigation_margin">5dp</dimen>

增加底部导航栏的高度,默认的底部导航栏的高度是 56dp

<dimen tools:override="true" name="design_bottom_navigation_height">84dp</dimen>

设置选中后字体不变,我们现在设置的选中的时候字体会变大,设置为不变:

<dimen tools:override="true" name="design_bottom_navigation_text_size">12sp</dimen>
<dimen tools:override="true" name="design_bottom_navigation_active_text_size">12sp</dimen>

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值