Why BadgeDrawable is not displayed anywhere? I'm trying to add on MaterialCardView
, MaterialButton
etc. It's not showing. Anyone have ideas how to fix this? Or have the same library that replacing this?
Here's code:
val badgeDrawable = BadgeDrawable.create(holder.itemView.context)
badgeDrawable.number = 10
badgeDrawable.badgeGravity = BadgeDrawable.TOP_END
badgeDrawable.backgroundColor = holder.itemView.context.getColor(R.color.colorAccent)
holder.itemView.home_cardview.overlay.add(badgeDrawable)
badgeDrawable.updateBadgeCoordinates(holder.itemView.home_cardview, null)
This method not working too:
BadgeUtils.attachBadgeDrawable(badgeDrawable, anchor, null);
By the way in new version compatBadgeParent is required field
You can apply the BadgeDrawable
to a MaterialCardView
or a MaterialButton
using a layout as:
<FrameLayout
android:id="@+id/layout"
android:clipChildren="false"
android:clipToPadding="false"
..>
<com.google.android.material.card.MaterialCardView
android:id="@+id/card"
.../>
</FrameLayout>
Then just use the method BadgeUtils.attachBadgeDrawable
.
For example with a CardView
:
MaterialCardView cardview = findViewById(R.id.card);
cardview.setClipToOutline(false); //Important with a CardView
cardview.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
BadgeDrawable badgeDrawable = BadgeDrawable.create(MainActivity.this);
badgeDrawable.setNumber(15);
BadgeUtils.attachBadgeDrawable(badgeDrawable, cardview, findViewById(R.id.layout));
cardview.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
For a Button
:
<FrameLayout
android:id="@+id/layout"
android:clipChildren="false"
android:clipToPadding="false">
<com.google.android.material.button.MaterialButton
android:id="@+id/button"
../>
</FrameLayout>
and then a similar code:
button.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
BadgeDrawable badgeDrawable = BadgeDrawable.create(MainActivity.this);
badgeDrawable.setNumber(7);
badgeDrawable.setBackgroundColor(......);
badgeDrawable.setVerticalOffset(20);
badgeDrawable.setHorizontalOffset(15);
BadgeUtils.attachBadgeDrawable(badgeDrawable, button, findViewById(R.id.layout));
button.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
Here is the solution posted by @0X0nosugar on my question so please go check out his answer and give him a thumbs up. Links placed above, thank you!
BottomNavigationView.getOrCreateBadge()
does not only assign the BadgeDrawable
as foreground Drawable, but it also sets the drawable bounds. Without this step, they stay at (0,0,0,0), so there is nothing to draw.
In order to set the bounds, let's introduce an extension function for BadgeDrawable
/**
* Inspired by BadgeUtils in com.google.android.material library
*
* Sets the bounds of a BadgeDrawable
*/
private fun BadgeDrawable.setBoundsFor(@NonNull anchor: View, @NonNull parent: FrameLayout){
val rect = Rect()
parent.getDrawingRect(rect)
this.setBounds(rect)
this.updateBadgeCoordinates(anchor, parent)
}
Use this function with your BadgeDrawable for FrameLayout:
private fun setFindShiftBadge(state: HomeState) {
val findShiftsBadge = BadgeDrawable.create(this)
// configure the badge drawable
findShiftsBadge.badgeGravity = BadgeDrawable.TOP_END
findShiftsBadge.backgroundColor = resources.getColor(R.color.colorWhite)
findShiftsBadge.badgeTextColor = resources.getColor(R.color.colorPrimary)
findShiftsBadge.number = state.availableShifts.size
// set bounds inside which it will be drawn
findShiftsBadge.setBoundsFor(btn_badge, home_framelayout)
// assign as foreground drawable
home_framelayout.foreground = findShiftsBadge
}
You can use the following function without FrameLayout in Kotlin way as:
view is the component where you want to put the notification badge!
@SuppressLint("UnsafeExperimentalUsageError")
private fun initBadge(view : View, nbrNotification : Int) {
if(nbrNotification == 0) return // Don't show the badge
view.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
BadgeDrawable.create(requireContext()).apply {
number = nbrNotification
verticalOffset = 70
horizontalOffset = 70
//badgeDrawable.setBackgroundColor() #to change the background color
BadgeUtils.attachBadgeDrawable(this, view)
}
view.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
})
}
verify the version that are you using, I am using:
com.google.android.material:material: 1.1.0-beta01
and try with this:
bottomNavigationView.getOrCreateBadge(R.id.menu_item_notifications).apply {
backgroundColor = resources.getColor(R.color.red)
badgeTextColor = resources.getColor(R.color.white)
maxCharacterCount = 3
number = 10 //should be change
isVisible = true
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With