有没有办法在API 25中引入的Google官方BottomNavigationView菜单项上显示通知徽章?

Waq*_*qas 11 android android-layout

我一直在尝试BottomNavigationView在API 25中发布.我想在底部导航栏的其中一个菜单项上显示通知徽章(比如一个带或不带计数的小蓝圈).

我有一个选择器drawable,其中我添加了检查true和检查错误状态与灰色drawable,其上有一个蓝点.当用户导航到其他导航项时,整个菜单按钮变为灰色和徽章.我知道这是因为itemIconTint应用于drawable这是因为具有不同颜色徽章作为图标的一部分将不起作用.有没有其他方法来实现这一目标?

<android.support.design.widget.BottomNavigationView
    android:id="@+id/bottom_navigation"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="@color/white"
    app:itemIconTint="@color/selector_bottom_nav"
    app:itemTextColor="@color/selector_bottom_nav"
    android:layout_gravity="bottom"
    app:menu="@menu/menu_bottom_nav">
</android.support.design.widget.BottomNavigationView>
Run Code Online (Sandbox Code Playgroud)

这就是我使用它的方式.以itemIconTint编程方式删除和更改图标可用没有帮助.

在Android开发者身上我什么都没找到,而且它也很新,网上也没有.

底部导航栏有自定义库,但我正在寻找官方库的支持.

任何想法,任何人?

Waq*_*qas 3

回答我自己的问题:

我最终在我的布局中放置了 2 个ImageViews具有可绘制徽章和可见性的徽章GONE。我这样计算徽章的位置:

private void calculateBadgesPosition() {
int totalNavItems = 3;
        for(int i = 0 ; i < bottomNavigation.getChildCount() ; i++) {
            View view =  bottomNavigation.getChildAt(i);

// Since Y remains same for all badges at least in my case.
// 1.3 is a factor that fits my placement of badge.
            double y = getResources().getDisplayMetrics().heightPixels - (view.getMeasuredHeight() * 1.3);
            if(image2ndItemBadge != null) {
                float x = getResources().getDisplayMetrics().widthPixels/2 + imageClassroomBadge.getMeasuredWidth()/2;

                image2ndItemBadge.setX(x);
                image2ndItemBadge.setY((float)y);
                image2ndItemBadge.requestLayout();
            }
// Since BottomNavigationView items are equally distributed you can find
// the right position for 3rd item (in my case last item) by dividing
// BottomNavigationView width by 3 and then by 2 to get the middle of that
// item, which was needed in my case.
            if(image3rdItemBadge != null) {
                float x = getResources().getDisplayMetrics().widthPixels - ((view.getMeasuredWidth()/totalNavItems)/2);

                image3rdItemBadge.setX(x);
                image3rdItemBadge.setY((float)y);
                image3rdItemBadge.requestLayout();
            }
            // BottomNavigationView count should always be 1 
            // but I observed the count was 2 in API 19. So I break after first iteration. 
            break;
        }
    }
Run Code Online (Sandbox Code Playgroud)

您可以删除 for 循环,只检查子项计数是否大于 0 并获取该子项。我在 onCreate 的末尾调用上面的方法,如下所示:

ViewTreeObserver viewTreeObserver = getWindow().getDecorView().getViewTreeObserver();
            viewTreeObservier.addOnGlobalLayoutListener (new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    calculateBadgesPosition();
                    getWindow().getDecorView().getViewTreeObserver().removeOnGlobalLayoutListener(this);
                }
            });
Run Code Online (Sandbox Code Playgroud)

ImageView不属于可绘制项目一部分的徽章BottomNavigationView不会受到BottomNavigationView选择/取消选择项目时应用的色调的影响。另外,如果您发现您的徽章没有出现,请尝试给它一个更高的elevation8 或 16 或其他值。就我而言,我的徽章留在了后面BottomNavigationView可能是因为它具有更高的海拔或 Z 索引。

我用 3 种不同的屏幕尺寸对此进行了测试,所有屏幕的位置都是相同的。

我希望这可以帮助任何面临类似官方问题的人BottomNavigationView

另外,如果您有更好的方法,请分享。