Android中修改BottomNavigationBar上BadgeDrawable的字体
我明白你遇到的困扰了——在Material Components 1.3.0-alpha03版本里,直接通过XML样式设置BadgeDrawable的字体确实不会生效,因为这个版本的BadgeDrawable并没有实现读取android:typeface、font或fontFamily这些属性的逻辑,只有布局相关的属性(比如badgeGravity)能正常工作。
下面是可行的解决方案,通过代码动态给BadgeDrawable设置自定义字体:
步骤1:获取目标BadgeDrawable实例
首先找到你的BottomNavigationView,并获取对应菜单项的BadgeDrawable:
// Kotlin代码 val bottomNav = findViewById<BottomNavigationView>(R.id.your_bottom_nav_id) val badge = bottomNav.getOrCreateBadge(R.id.your_menu_item_id)
// Java代码 BottomNavigationView bottomNav = findViewById(R.id.your_bottom_nav_id); BadgeDrawable badge = bottomNav.getOrCreateBadge(R.id.your_menu_item_id);
步骤2:加载自定义字体
从assets目录加载你的自定义字体文件(确保字体文件放在src/main/assets/fonts/目录下,路径和文件名对应):
// Kotlin代码 val customTypeface = Typeface.createFromAsset(assets, "fonts/custom_font.ttf")
// Java代码 Typeface customTypeface = Typeface.createFromAsset(getAssets(), "fonts/custom_font.ttf");
步骤3:通过反射设置字体到BadgeDrawable的画笔
由于1.3.0-alpha03版本的BadgeDrawable没有暴露设置字体的公共API,我们需要通过反射获取它内部的文本画笔,然后设置自定义字体:
// Kotlin代码 try { val paintField = BadgeDrawable::class.java.getDeclaredField("textPaint") paintField.isAccessible = true val textPaint = paintField.get(badge) as Paint textPaint.typeface = customTypeface badge.invalidateSelf() // 触发重新绘制,让字体生效 } catch (e: NoSuchFieldException) { e.printStackTrace() } catch (e: IllegalAccessException) { e.printStackTrace() }
// Java代码 try { Field paintField = BadgeDrawable.class.getDeclaredField("textPaint"); paintField.setAccessible(true); Paint textPaint = (Paint) paintField.get(badge); textPaint.setTypeface(customTypeface); badge.invalidateSelf(); // 触发重新绘制,让字体生效 } catch (NoSuchFieldException | IllegalAccessException e) { e.printStackTrace(); }
补充说明
- 如果后续你升级Material库到1.4.0及以上版本,可以关注官方是否支持了通过XML样式设置Badge字体,那时就可以不用反射方案了。
- 确保字体文件的路径和文件名完全匹配,避免加载失败。
内容的提问来源于stack exchange,提问作者asajadi84
相关产品推荐
相关产品推荐

