Badge attached to CardView doesn't show

87 views Asked by At

I want to create and attach a badge to a CardView inflated from xml layout inside a RecyclerView.ViewHolder:

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MenuItemViewHolder {
        val layoutView = LayoutInflater.from(parent.context).inflate(R.layout.menu_item_card, parent, false)
        val cardView = layoutView.findViewById<CardView>(R.id.card_view)
        val badgeDrawable = BadgeDrawable.create(parent.context)
        badgeDrawable.isVisible = true
        badgeDrawable.number = 3
        badgeDrawable.horizontalOffset = 1
        badgeDrawable.verticalOffset = -1
        BadgeUtils.attachBadgeDrawable(badgeDrawable, cardView)
        return MenuItemViewHolder(layoutView)
}

I have tried different variations for the BadgeDrawable attributes isVisible, number, horizontalOffset, verticalOffset. So far, without success.

The layout file has the CardView element nested under a ConstraintLayout:

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <androidx.cardview.widget.CardView
        android:id="@+id/card_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            ...
        </LinearLayout>
    </androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
1

There are 1 answers

3
Blundell On

You should link the docs really :-) https://developer.android.com/reference/com/google/android/material/badge/BadgeUtils#attachBadgeDrawable(com.google.android.material.badge.BadgeDrawable,%20android.view.View,%20android.widget.FrameLayout)

docs

Attaches a BadgeDrawable to its associated anchor

so you are trying to anchor it to the androidx.cardview.widget.CardView

For pre-API 18, the BadgeDrawable will be set as the foreground of a FrameLayout that is an ancestor of the anchor

Your CardView will need a FrameLayout ancestor. It's parent at the moment is a CoordinatorLayout, and its parent is a RecyclerView, which probably eventually is in a FrameLayout however that is not near where you want the Badge to be displayed.

Either:

  1. If you create a FrameLayout inside of your CardView then find a view inside of that, it'll be anchored inside your card.

  2. Create FrameLayout around your CardView, so that CardView has a very close ancestor FrameLayout for it to attach to.

You could also try

    badgeDrawable.horizontalOffset = 50
    badgeDrawable.verticalOffset = 50

just for debugging to push the badge more into the screen rather than right on the edge (edge of whatever FrameLayout it is picking).