【Android】BottomNavigationView实现底部导航栏
一、BottomNavigationView的介绍及常用属性
BottomNavigationView是官方提供的可以实现自定义底部导航栏的控件,推荐底部只有3-5个菜单选项时使用,因为超过5个选项会触发自动收缩,即只显示图标不显示文字。
常用属性
app:itemTextColor 文字的颜色,可以通过selector来控制选中和未选中的颜色
app:itemIconTint 图标的颜色,可以通过selector来控制选中和未选中的颜色
app:itemIconSize 图标大小,默认24dp
app:iteamBackground 背景颜色,默认是主题的颜色
app:itemRippleColor 点击后的水波纹颜色
app:itemTextAppearanceActive 设置选中时文字样式
app:itemTextAppearanceInactive 设置默认的文字样式
app:itemHorizontalTranslationEnabled 在label visibility 模式为selected时item水平方向移动
app:elevation 控制控件顶部的阴影
app:labelVisibilityMode 文字的显示模式
app:menu 指定菜单xml文件(文字和图片都写在这个里面)
二、BottomNavigationView的使用步骤
1.在布局文件中加入BottomNavigationView控件,使用app:menu="@menu/main_nav_bottom_menu"指定目录文件,将底部导航栏的图标和文字加载到控件中
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:id="@+id/main"android:layout_height="match_parent"android:background="@color/white"android:fitsSystemWindows="true"tools:context=".all.MainActivity"><androidx.viewpager2.widget.ViewPager2android:id="@+id/main_viewpager"android:layout_width="match_parent"android:layout_height="match_parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintBottom_toTopOf="@id/bottom_navigation"></androidx.viewpager2.widget.ViewPager2><com.google.android.material.bottomnavigation.BottomNavigationViewandroid:id="@+id/bottom_navigation"android:layout_width="match_parent"android:layout_height="55dp"android:elevation="1dp"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintBottom_toBottomOf="parent"app:menu="@menu/main_nav_bottom_menu"android:background="@drawable/bottom_nav_view"app:labelVisibilityMode="labeled"app:itemBackground="@drawable/bottom_nav_view"app:itemTextColor="@color/main_item_text_selector"app:itemActiveIndicatorStyle="@null"style="@style/CustomBottomNavigationView"app:itemRippleColor="@color/white"></com.google.android.material.bottomnavigation.BottomNavigationView><ImageViewandroid:id="@+id/bottom_navigation_add"android:layout_width="48dp"android:layout_height="60dp"android:src="@drawable/add"android:elevation="200dp"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
2.创建目录文件
在res文件夹下创建自定义目录文件,在item项中设置底部导航栏的文字与图标
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"><itemandroid:id="@+id/bottom_nav_mainpage"android:title="首页"/><itemandroid:id="@+id/bottom_nav_market"android:title="市集"/><itemandroid:title=""android:id="@+id/bottom_nav_add"/><itemandroid:id="@+id/bottom_nav_message"android:title="消息"/><itemandroid:id="@+id/bottom_nav_mine"android:title="我"/></menu>
3.设置BottomNavigationView的属性
(1)labelVisibilityMode:控制文本显示
labeled:强制所有导航项始终显示文本标签
auto:默认值,智能显示
selected:仅选中项显示
unlabeled:全部隐藏
(2)app:itemTextColor:文本颜色状态选择器
这个属性可修改文字选中和未选中的颜色
在res目录下新建color文件夹,新建一个文字颜色状态资源文件
在其中设置选中和未选中的颜色
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:color="@color/black" android:state_checked="true" /><item android:color="#CDCDCD" />
</selector>
接着修改布局文件中的代码,添加itemTextColor属性,制定了一个文本颜色选择状态器
app:itemTextColor="@color/main_item_text_selector"
(3)app:itemIconTint:图标颜色状态选择器
这个属性可修改图标选中和未选中的颜色
为了和文本颜色保持一致,可以复用上面的文字颜色状态资源文件,在布局文件中添加itemIconTint属性
app:itemIconTint="@color/main_item_text_selector"
(4)itemRippleColor:设置点击水波纹效果
可以设置水波纹点击的颜色
app:itemRippleColor="@color/white"
如果想禁用水波纹效果,可以设置
app:itemRippleColor="@null"
(5)TextAppearance:设置文本样式
temTextAppearanceActive:设置文本选中的style风格
itemTextAppearanceInactive:设置文本未选中的style风格
首先在res目录下的values文件夹下新建styles.xml文件
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"><!-- Base application theme. --><style name="MainItemTextSelectStyle" ><item name="android:textSize">20sp</item></style><style name="MainItemTextUnSelectStyle" ><item name="android:textSize">15sp</item></style>
</resources>
之后修改布局文件,添加
app:itemTextAppearanceActive="@style/MainItemTextSelectStyle"app:itemTextAppearanceInactive="@style/MainItemTextUnSelectStyle"
(6)itemIconSize:设置图标大小
这个属性可以自定义图标尺寸,默认为24dp
app:itemIconSize="30dp"
(7)app:itemActiveIndicatorStyle:设置当前选中菜单项的激活指示器的样式
app:itemActiveIndicatorStyle="@null":取消点击时的背景颜色
4.添加导航栏角标
public class MainActivity extends AppCompatActivity {private ViewPager2 totalViewPager2;private BottomNavigationView bottomNavigationView;public void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);totalViewPager2=findViewById(R.id.main_viewpager);List<Integer> list=new ArrayList<>();list.add(1);totalViewPager2.setAdapter(new MainPageFragmentAdapter(this,list));ImageView add=(ImageView) findViewById(R.id.bottom_navigation_add);add.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {new BottomSheetFragment().show(getSupportFragmentManager(), "tag");}});bottomNavigationView=findViewById(R.id.bottom_navigation);addNovigationBadge();}private void addNovigationBadge(){BadgeDrawable myBadge = bottomNavigationView.getOrCreateBadge(R.id.bottom_nav_message);myBadge.setNumber(6); // 显示数字6myBadge.setBackgroundColor(ContextCompat.getColor(this, R.color.red)); // 设置红色背景myBadge.setBadgeTextColor(Color.WHITE); // 设置文字颜色为白色myBadge.setMaxCharacterCount(3); // 最多显示3个字符(显示99+)myBadge.setVerticalOffset(40); // 垂直向下偏移40dpmyBadge.setHorizontalOffset(5); // 水平向左偏移5dpmyBadge.setVisible(true);}}
在MainActivity中,首先通过findViewById获取到BottomNavigationView的实例,通过
addBadgeToNavigationItem方法为“微信”选项添加角标,在addBadgeToNavigationItem方法中,通过BottomNavigationView方法中的getOrCreateBadge方法获取到“微信”选项的角标实例,接着使用BadgeDrawable中的一系列方法设置角标的各种参数,
5.设置导航栏按键的点击事件
在活动中获取BottomNavigationView的实例,通过实例设置setOnItemSelectedListener方法,在其中实现被点击的逻辑
bottomNavigationView.setOnItemSelectedListener(item -> {int itemId = item.getItemId();if (itemId == R.id.bottom_nav_mainpage) {Toast.makeText(this, "首页被点击", Toast.LENGTH_SHORT).show();}return true;});