Is there a way to display notification badge on Google's official BottomNavigationView menu items introduced in API 25?

前端 未结 3 1982
野性不改
野性不改 2020-12-31 10:49

I have been trying BottomNavigationView released in API 25. I want to display a notification badge (say a small blue circle with or without a count in it) on on

3条回答
  •  盖世英雄少女心
    2020-12-31 11:06

    Answering my own question:

    I ended up putting 2 ImageViews with badge drawable and visiblity GONE in my layout. I calculate positioning of the badges like this:

    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;
            }
        }
    

    You can remove the for loop and just check if child count greater than 0 and get that child. I call the above method at the end of onCreate like this:

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

    Badge ImageView not being part of the BottomNavigationView Items drawable will not be effected by tint that BottomNavigationView applies on selection/un selection of item. Also if you see your badge not appearing try giving it a higher elevation 8 or 16 or whatever. In my case my badge stayed behind BottomNavigationView probably because it has higher elevation or Z index.

    I tested this with 3 different screen sizes and the positioning was same on all.

    I hope this helps anyone facing similar issue with official BottomNavigationView.

    Also if you have a better approach please share it.

提交回复
热议问题