Android 如何为BottomNavigationView选中项添加上部边框?
解决方案
问题根因
你当前代码不生效主要有两个核心原因:
shape="line"默认会在drawable渲染区域垂直居中,所以描边会显示在item的中间位置,而非顶部- 布局高度错用了sp单位,sp会随系统字体大小变化,导致你预设的高度和描边位置计算出现偏差
方案1:修改drawable选择器(最优方案,无需修改其他逻辑)
第一步:修改Activity.xml中BottomNavigationView属性
<com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/bottomNavigationView" android:layout_width="match_parent" android:layout_height="60dp" <!-- 把sp改成dp,布局尺寸统一用dp单位 --> app:itemBackground="@drawable/bottom_navigation_border" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:menu="@menu/bottom_nav_menu" />
第二步:重写bottom_navigation_border.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 选中态:顶部描边 --> <item android:state_checked="true"> <!-- 60dp总高度 - 6dp描边高度 = 54dp,通过底部内边距把描边顶到顶部 --> <inset android:insetBottom="54dp"> <shape android:shape="rectangle"> <solid android:color="@color/red_700"/> <!-- 底部圆角,对应你原来的5dp圆角需求 --> <corners android:bottomLeftRadius="5dp" android:bottomRightRadius="5dp"/> </shape> </inset> </item> <!-- 未选中态:透明背景,可根据需求修改为你要的导航栏底色 --> <item android:state_checked="false"> <shape android:shape="rectangle"> <solid android:color="@android:color/transparent"/> </shape> </item> </selector>
方案2:自定义item布局(适用于需要更多自定义效果的场景)
如果需要更复杂的选中效果,可以自定义每个item的布局:
- 新建布局文件
layout/bottom_nav_item.xml,自定义包含顶部边框、图标、文字的布局 - 在BottomNavigationView中添加属性
app:itemLayout="@layout/bottom_nav_item" - 正常设置menu即可,选中态的边框可以在自定义布局的选中状态监听里控制显隐
注意事项
- 不要给BottomNavigationView设置
app:itemPaddingTop,否则会导致顶部描边被向内挤压看不到 - 如果需要保留导航栏的背景色,直接给BottomNavigationView设置
android:background属性即可,不要在itemBackground里设置全局背景,避免每个item的背景重复渲染
内容的提问来源于stack exchange,提问作者pepperlove
相关产品推荐
相关产品推荐

