-
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的页面框架。
附上效果图:
BottomNavigationView实现页面底部导航栏
最新推荐文章于 2024-04-21 11:16:39 发布