阿里巴巴 二代征信 yii Momentjs HammerJS Font Awesome vue网站 进销存源码 js的点击事件 pip环境变量配置 less的比较级 matlab中不等于怎么表示 python如何实现多线程 input函数python python例子 javarandom java时间转换 java成员变量 java获取 javaenum java集合图 java项目下载 php连接mssql php抓取网页数据 骰子表情 有线网卡驱动下载 早早省 python延时函数 骰子gif 保卫萝卜沙漠7攻略 神魔辅助 grep正则表达式 圣武枪魂 ps怎么做漂亮艺术字 掌门一对一官网下载 id页码怎么设置 机械键盘怎么关闭灯光 dw网页设计教程 pr怎么旋转视频画面 xd下载
当前位置: 首页 > 学习教程  > 编程语言

BottomNavigationView实现页面底部导航栏

2020/11/24 11:17:33 文章标签: 测试文章如有侵权请发送至邮箱809451989@qq.com投诉后文章立即删除

BottomNavigationView基本使用&#xff08;静态配置&#xff09; 在Activity的xml布局中添加BottomNavigationView引用 <!--导航菜单--> <com.google.android.material.bottomnavigation.BottomNavigationViewandroid:id"id/nav_main_bottom"android:layout…

  • BottomNavigationView基本使用(静态配置)

    在Activity的xml布局中添加BottomNavigationView引用

    <!--导航菜单-->
    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/nav_main_bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:itemBackground="@android:color/transparent"
        app:itemTextAppearanceActive="@style/bottom_nav_text_selected"
        app:itemTextAppearanceInactive="@style/bottom_nav_text_normal"
        app:itemTextColor="@drawable/selector_tab_menu_text"
        app:menu="@menu/bottom_nav" />
    

    以上相关属性介绍:

    itemBackground:为BottomNavigationView布局指定背景色,优先级高于background属性

    itemRippleColor:设置条目点击时水波纹颜色,设置itemBackground属性时,该属性无效

    itemTextAppearanceActive:设置条目选中时text样式

    itemTextAppearanceInactive:设置条目未选中时text样式

    itemTextColor:条目text颜色,可以使用选择器

    itemIconTint:为条目图标着色,需要在代码中设置setItemIconTintList(null)去掉默认着色

    menu:指定条目菜单

    <!--底部导航栏文字样式-->
    <style name="bottom_nav_text_normal">
        <item name="android:textSize">@dimen/font_13</item>
        <item name="android:paddingTop">10dp</item>
    </style>
    <style name="bottom_nav_text_selected">
        <item name="android:textSize">@dimen/font_15</item>
        <item name="android:paddingTop">15dp</item>
    </style>
    
    <!--selector_tab_menu_text.xml-->
    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:color="@color/tab_menu_text_selected" android:state_selected="true" />
        <item android:color="@color/tab_menu_text_normal" />
    </selector>
    
    <!--bottom_nav.xml-->
    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
        <item
            android:id="@+id/nav_main"
            android:icon="@drawable/selector_tab_menu_icon_main"
            android:title="@string/nav_tab_main" />
        <item
            android:id="@+id/nav_find"
            android:icon="@drawable/selector_tab_menu_icon_find"
            android:title="@string/nav_tab_find" />
        <item
            android:id="@+id/nav_mine"
            android:icon="@drawable/selector_tab_menu_icon_mine"
            android:title="@string/nav_tab_mine" />
    </menu>
    

    bottom_nav中静态指定了三个item,id为每个item独有的标志,点击事件的时候会用到,title属性指定item的名称,例如“我的”、“发现”等,icon属性为item指定图标,这里使用了selector选择器,如下:

    <!--selector_tab_menu_icon_main.xml-->
    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@mipmap/ic_main_selected" android:state_selected="true" />
        <item android:drawable="@mipmap/ic_main_normal" />
    </selector>
    
    <!--selector_tab_menu_icon_find.xml-->
    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@mipmap/ic_find_selected" android:state_selected="true" />
        <item android:drawable="@mipmap/ic_find_normal" />
    </selector>
    
    <!--selector_tab_menu_icon_mine.xml-->
    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@mipmap/ic_mine_selected" android:state_selected="true" />
        <item android:drawable="@mipmap/ic_mine_normal" />
    </selector>
    

    至此静态创建方式完成。

  • BottomNavigationView基本使用(动态添加和删除)

    在Activity的xml布局中同样需要添加BottomNavigationView引用

    <!--导航菜单-->
    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/nav_main_bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:itemBackground="@android:color/white"
        app:itemTextAppearanceActive="@style/bottom_nav_text_selected"
        app:itemTextAppearanceInactive="@style/bottom_nav_text_normal"
        app:itemTextColor="@drawable/selector_tab_menu_text"/>
    

    注意:这里没有添加menu属性

    代码实现初始化添加:

    private void addMenu() {
        Menu menu = navView.getMenu();
        //添加首页
        menu.add(0, 1, 0, "首页").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
        menu.getItem(0).setIcon(R.drawable.selector_tab_menu_icon_main);
        //添加我的模块
        menu.add(0, 3, 2, "我的").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
        menu.getItem(1).setIcon(R.drawable.selector_tab_menu_icon_mine);
    }
    

    现在再添加一个“发现”板块,放到中间位置:

    public void addNewMenu(View view) {
        Menu menu = navView.getMenu();
        menu.add(0, 2, 1, "发现").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
        menu.getItem(1).setIcon(R.drawable.selector_tab_menu_icon_find);
    }
    

    上面添加方法中使用了Menu的构造函数:add(int groupId, int itemId, int order, CharSequence title);

    第一个参数指定组id,第二个参数致命条目id(点击事件的时候要用),第三个参数指定条目顺序,第四个为条目标签名称。

    上面我把“首页”放到了第一个位置,“我的”放到了第三个位置,添加的“发现”放到了第二个位置。设置icon时有一个细节需要注意,在初始化条目完成后,BottomNavigationView只有两个item,因此getItem(0)和getItem(1)分别是首页和我的板块item实例,但是添加“发现”板块之后就变成了三个,而且发现板块放到了第二个位置,因此设置icon时候我们是通过menu.getItem(1)拿到发现item的实例,而不是getItem(2)。

    删除条目:

    public void removeMenu(View view) {
        Menu menu = navView.getMenu();
        menu.removeItem(2);
    }
    

    removeItem(2)方法中的参数“2”指的是itemId并不是条目索引。

    注意:BottomNavigationView对添加的menu个数有限制,最多不能超过5个,如果超过5个会报以下错误:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rJkEsgYS-1606187401040)(H:\Android知识体系\知识架构图片\第一部分\第一章\1.1\1.1.5\BottomNavigationView添加超过5个.png)]

  • 后台分发动态加载方案简述

    上面一小节中虽然实现了Menu的动态添加和删除,但是还无法满足后台分发动态加载的要求,底部导航的动态需要做到以下几个方面动态配置:

    选择状态下icon

    正常状态下icon

    选择状态下label颜色

    正常状态下label颜色

    label文案

    menu个数

    因此,上一小节中icon的加载方案还需要优化。

    换一种drawable加载方式实现,如下:

    private static final int[] STATE_NORMAL = {-android.R.attr.state_selected};//-代表此属性为false
    private static final int[] STATE_SELECTED = {android.R.attr.state_selected};
    
    private void addMenu() {
        Menu menu = navView.getMenu();
        //添加首页
        menu.add(0, 1, 0, "首页").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
        //设置首页icon
        StateListDrawable mainDrawable = new StateListDrawable();
        Bitmap mainSelectedBitmap = BitmapFactory.decodeResource(getResources(), 			R.mipmap.ic_main_selected);
        BitmapDrawable mainSelectedIcon = new BitmapDrawable(mainSelectedBitmap);
        mainDrawable.addState(STATE_SELECTED, mainSelectedIcon);
        Bitmap mainNormalBitmap = BitmapFactory.decodeResource(getResources(), 				R.mipmap.ic_main_normal);
        BitmapDrawable mainNormalIcon = new BitmapDrawable(mainNormalBitmap);
        mainDrawable.addState(STATE_NORMAL, mainNormalIcon);
        menu.getItem(0).setIcon(mainDrawable);
        //添加我的模块
        menu.add(0, 3, 2, "我的").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
        //设置我的模块icon
        StateListDrawable mineDrawable = new StateListDrawable();
        Bitmap mineSelectedBitmap = BitmapFactory.decodeResource(getResources(), 			R.mipmap.ic_mine_selected);
        BitmapDrawable mineSelectedIcon = new BitmapDrawable(mineSelectedBitmap);
        mineDrawable.addState(STATE_SELECTED, mineSelectedIcon);
        Bitmap mineNormalBitmap = BitmapFactory.decodeResource(getResources(), 				R.mipmap.ic_mine_normal);
        BitmapDrawable mineNormalIcon = new BitmapDrawable(mineNormalBitmap);
        mineDrawable.addState(STATE_NORMAL, mineNormalIcon);
        menu.getItem(1).setIcon(mineDrawable);
    }
    

    使用menuItem的setIcon(Drawable icon)重载方法设置,需要设置选择状态下和非选择状态下的icon,这里用StateListDrawable就可以解决。另一个问题,一般后台都是通过url的形式分发icon的,因此我们还需要将对应状态的图片异步下载下来,然后存放至对应的文件夹下,待下载并保存成功后通过BitmapFactory.decodeFile()方法获取对应的Bitmap,然后对应的BitmapDrawable实例也就能获取到了。具体实现代码这里不再多做介绍,大体思路就是如此,有兴趣的小伙伴们可以详细研究一下。

  • 整体页面框架搭建(静态化配置方案)

    静态化配置底部导航栏上文中已经介绍过,这里不再赘述。接下来直接创建对应的Fragment:

    /**
     * 初始化底部导航选择
     */
    private void initNav() {
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction transaction = fm.beginTransaction();
        if (mMainFrag == null) {
            mMainFrag = new MainFragment();
            mFragList.add(mMainFrag);
            transaction.add(R.id.fl_container, mMainFrag);
        }
        transaction.commit();
    }
    

    BottomNavigationView添加item点击点听:

    @SuppressLint("NonConstantResourceId")
    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction transaction = fm.beginTransaction();
        switch (item.getItemId()) {
            case R.id.nav_main: //首页
                if (mMainFrag == null) {
                    mMainFrag = new MainFragment();
                    mFragList.add(mMainFrag);
                    transaction.add(R.id.fl_container, mMainFrag);
                }
                for (Fragment frag : mFragList) {
                    transaction.hide(frag);
                }
                transaction.show(mMainFrag);
                break;
            case R.id.nav_find: //发现
                if (mFindFrag == null) {
                    mFindFrag = new FindFragment();
                    mFragList.add(mFindFrag);
                    transaction.add(R.id.fl_container, mFindFrag);
                }
                for (Fragment frag : mFragList) {
                    transaction.hide(frag);
                }
                transaction.show(mFindFrag);
                break;
            case R.id.nav_mine: //我的
                if (mMineFrag == null) {
                    mMineFrag = new MineFragment();
                    mFragList.add(mMineFrag);
                    transaction.add(R.id.fl_container, mMineFrag);
                }
                for (Fragment frag : mFragList) {
                    transaction.hide(frag);
                }
                transaction.show(mMineFrag);
                break;
        }
        transaction.commit();
        return true;
    }
    

    很容易就实现了底部导航菜单切换展示对应模块Fragment的页面框架。
    附上效果图:
    在这里插入图片描述


本文链接: http://www.dtmao.cc/news_show_400438.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?