2

I've implemented a counter badge according to the following thread.

Then I expended it a bit to remove the badge from the navigation item when notification count is 0:

fun setInboxIcon(count: Int) {
    val bottomNavigationMenuView = bottomNavigation.getChildAt(0) as BottomNavigationMenuView
    val bottomNavigationItemView = bottomNavigationMenuView.getChildAt(3) as BottomNavigationItemView
    val inboxBadge = LayoutInflater.from(context).inflate(R.layout.inbox_icon_layout, bottomNavigationMenuView, false)
    notificationCount = inboxBadge.findViewById(R.id.notification_count)

    if (count == 0) {
        notificationCount.visibility = GONE
        notificationCount.text = ""
        bottomNavigationItemView.removeView(inboxBadge) // <- nothing happens
    } else {
        notificationCount.visibility = VISIBLE
        notificationCount.text = Math.min(count, 9).toString()
        bottomNavigationItemView.addView(inboxBadge)
    }

    bottomNavigation.invalidate()
}

Problem is that the badge isn't removed when notification count is 0, and I can't seem to find out why.

Ambran
  • 2,367
  • 4
  • 31
  • 46
  • Where is the problem? obviously you have do something opposite to `bottomNavigationItemView.addView(inboxBadge);` ... also what is the point of inflating the view if count is 0 ? – Selvin Jan 25 '18 at 12:12
  • afterr edit: now you are removing newly inflated item ... which obviously doesn't exist inside bottomNavigationItemView ... so oviously "nothing happens" ... – Selvin Jan 25 '18 at 12:15
  • Obvious solution: 1. create inboxBadge only once 2. store the references to it 3. make use of setVisibility – Selvin Jan 25 '18 at 12:18
  • @Selvin I've also tried declaring the badge globally (which should point to the same instance) and referring to it upon removal. Doesn't help either. – Ambran Jan 25 '18 at 12:19
  • People, please have the decency to explain your downvotes instead of just downvoting a perfectly legitimate question. – Ambran Jan 25 '18 at 13:39
  • 1
    He DOES have a problem. why the downvoting? in the line `notificationCount.setVisibility(GONE);` he is setting the visibility of a new instantiated `notificationCount`. see his answer where he deletes the previously instantiated View! – Hesham Yassin Aug 03 '18 at 12:17

2 Answers2

4

Found a solution.

I'm locating the actual badge in the menu item and removing it before eventually producing a new one. It's the only approach that works for me:

fun setInboxIcon(count: Int) {
    val bottomNavigationMenuView = bottomNavigation.getChildAt(0) as BottomNavigationMenuView
    val bottomNavigationItemView = bottomNavigationMenuView.getChildAt(3) as BottomNavigationItemView
    val badge = LayoutInflater.from(context).inflate(R.layout.inbox_icon_layout, bottomNavigationMenuView, false)
    val notificationCount = badge.findViewById(R.id.notification_count)

    // Reset current badge
    bottomNavigationItemView.removeView(bottomNavigationItemView.getChildAt(2))

    // Add new badge
    if (count > 0) {
        notificationCount.text = Math.min(count, 9).toString()
        bottomNavigationItemView.addView(badge)
    }
}
Ambran
  • 2,367
  • 4
  • 31
  • 46
0

In my case, I added TAG in badgeView and find the view by TAG to remove it.

private val TAG = "Badge"

fun addOrRemoveBadgeView(bottomNav: BottomNavigationView, show: Boolean) {
    val menuView = bottomNav.getChildAt(0) as BottomNavigationMenuView
    val itemView = menuView.getChildAt(3) as BottomNavigationItemView
    val notificationsBadge = LayoutInflater.from(bottomNav.context)
                                .inflate(R.layout.badge_layout,menuView, false)
    notificationsBadge.tag = TAG

    if (show) {
        itemView.addView(notificationsBadge)
    }
    else {
        val view = itemView.findViewWithTag<View>(TAG)
        itemView.removeView(view)
    }
}
Thwe
  • 83
  • 1
  • 2
  • 8