如何使用BadgeDrawable在汉堡导航菜单图标上添加Badge?
问题:如何用
BadgeDrawable给汉堡导航图标添加角标? 我已经用某种方法给按钮添加了Badge,现在想给汉堡导航菜单图标用同样方式添加Badge,但尝试后结果不符合预期。我找到的方案都没用到BadgeDrawable,以下是我的代码:
activity_main 布局代码
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drawerLayout_main" android:layout_width="match_parent" android:layout_height="match_parent" android:layoutDirection="rtl"> <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar_main" android:layout_width="match_parent" android:layout_height="wrap_content" /> </FrameLayout> <com.google.android.material.navigation.NavigationView android:id="@+id/navigationView_main" android:layout_width="250dp" android:layout_height="match_parent" /> </androidx.drawerlayout.widget.DrawerLayout>
MainActivity 代码
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); NavigationView navigationView = findViewById(R.id.navigationView_main); DrawerLayout drawerLayout = findViewById(R.id.drawerLayout_main); Toolbar toolbar = findViewById(R.id.toolbar_main); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this , drawerLayout, toolbar , 0b0, 0); drawerLayout.addDrawerListener(toggle); toggle.syncState(); navigationView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { BadgeDrawable badgeDrawable = BadgeDrawable.create(MainActivity.this); badgeDrawable.setVerticalOffset(25); badgeDrawable.setHorizontalOffset(15); BadgeUtils.attachBadgeDrawable(badgeDrawable, navigationView, null); navigationView.getViewTreeObserver().removeOnGlobalLayoutListener(this); } }); } }
当前效果

预期效果

我的问题:能否使用BadgeDrawable在汉堡导航菜单图标上添加Badge?
解决方案
完全可以用BadgeDrawable实现这个需求,你当前代码的问题是把角标绑定到了NavigationView上,而非汉堡图标本身。汉堡图标是ActionBarDrawerToggle生成的子View,属于Toolbar的子控件,我们需要定位到这个View再绑定角标。
修改后的代码如下:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); NavigationView navigationView = findViewById(R.id.navigationView_main); DrawerLayout drawerLayout = findViewById(R.id.drawerLayout_main); Toolbar toolbar = findViewById(R.id.toolbar_main); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this , drawerLayout, toolbar , 0b0, 0); drawerLayout.addDrawerListener(toggle); toggle.syncState(); // 监听Toolbar布局完成,定位汉堡图标View toolbar.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { // RTL布局下汉堡图标在Toolbar最左侧,对应最后一个子View;LTR布局下是第一个子View(getChildAt(0)) View hamburgerView = toolbar.getChildAt(toolbar.getChildCount() - 1); if (hamburgerView != null) { BadgeDrawable badgeDrawable = BadgeDrawable.create(MainActivity.this); // 设置角标显示的数字,不设置则默认显示小圆点 badgeDrawable.setNumber(3); // 根据布局方向调整偏移量,让角标贴合图标 badgeDrawable.setVerticalOffset(8); badgeDrawable.setHorizontalOffset(8); // 将角标绑定到汉堡图标View上 BadgeUtils.attachBadgeDrawable(badgeDrawable, hamburgerView, null); } // 移除监听避免重复执行 toolbar.getViewTreeObserver().removeOnGlobalLayoutListener(this); } }); } }
关键说明
- 汉堡图标是
Toolbar的子View,需根据布局方向(RTL/LTR)调整获取子View的索引; - 调用
badgeDrawable.setNumber()可设置角标数字,不调用则显示无数字的小圆点; - 调整
setVerticalOffset和setHorizontalOffset的值,可让角标位置完全匹配预期效果。
内容的提问来源于stack exchange,提问作者Nima Khalili
相关产品推荐
相关产品推荐

