Massimiliano Carosi
Massimiliano Carosi

Reputation: 284

I cannot display a badge over a floating action button for my Kotlin Android app

I am simply trying to add a badge to display a number in a small circle over my floating action button. I get this error:

java.lang.IllegalArgumentException: The style on this component requires your app theme to be Theme.MaterialComponents (or a descendant). at com.google.android.material.internal.ThemeEnforcement.checkTheme(ThemeEnforcement.java:241) at com.google.android.material.internal.ThemeEnforcement.checkMaterialTheme(ThemeEnforcement.java:215) at com.google.android.material.badge.BadgeDrawable.(BadgeDrawable.java:464) at com.google.android.material.badge.BadgeDrawable.createFromAttributes(BadgeDrawable.java:353) at com.google.android.material.badge.BadgeDrawable.create(BadgeDrawable.java:321) ...

when I do this:

val badge = BadgeDrawable.create(applicationContext)
BadgeUtils.attachBadgeDrawable(badge, binding.fab, null)

In my theme.xml file I have:

<resources xmlns:tools="http://schemas.android.com/tools">
    <style name="Theme.Made" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        <!-- Primary brand color. -->
        <item name="colorPrimary">@color/red</item>
        <item name="colorOnPrimary">@color/white</item>
        <!-- Secondary brand color. -->
        <item name="colorSecondary">@color/black</item>
        <item name="colorOnSecondary">@color/white</item>
        <!-- Status bar color. -->
        <item name="android:statusBarColor">@color/black</item>
        <!-- Customize your theme here. -->
    </style>

    <style name="Theme.Made.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

    <style name="Theme.Made.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />

    <style name="Theme.Made.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
</resources>

I have also a file themes.xml (night) but it is empty:

<resources xmlns:tools="http://schemas.android.com/tools"></resources>

In my AndroidManifest.xml I have:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"             xmlns:tools="http://schemas.android.com/tools">
    <application
        ...
        android:theme="@style/Theme.Made"
        ...
    >
    ...
    </application>
</manifest>

this is the layout of the main activity (where the floating action button is):

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    tools:context=".MainActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/Theme.Made.AppBarOverlay">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/Theme.Made.PopupOverlay" />

    </com.google.android.material.appbar.AppBarLayout>

    <include layout="@layout/content_main" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_marginEnd="@dimen/standard_margin"
        android:layout_marginBottom="16dp"
        app:srcCompat="@drawable/cart"
        android:contentDescription="@string/cart" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

the bindings are inflated by

binding = ActivityMainBinding.inflate(layoutInflater)

in the onCreate of the main activity.

What am I missing? why I get that error also if the theme is MaterialComponents? I have tried to change the theme to Theme.MaterialComponents.Light.DarkActionBar, Theme.MaterialComponents.Light.Bridge, ... like suggested in other questions, but the error is still presente. Thank you.

NB: i have already tried all what have been suggested in this link: similar question, indeed, from what I can see from my code, I am applying a MaterialComponents theme

Upvotes: 1

Views: 702

Answers (1)

Sohaib Ahmed
Sohaib Ahmed

Reputation: 3062

Update your code like this

binding.fab.viewTreeObserver.addOnGlobalLayoutListener(object : OnGlobalLayoutListener {
    override fun onGlobalLayout() {
        binding.fab.viewTreeObserver.removeOnGlobalLayoutListener(this)
        val badgeDrawable = BadgeDrawable.create(this@MainActivity)
        badgeDrawable.number = 3
        badgeDrawable.isVisible = true
        BadgeUtils.attachBadgeDrawable(badgeDrawable, binding.fab, null)
    }
})

Or

binding.fabBadge.doOnPreDraw {
    val badgeDrawable = BadgeDrawable.create(this@Question12_Badge)
    badgeDrawable.number = 3
    badgeDrawable.isVisible = true
    BadgeUtils.attachBadgeDrawable(badgeDrawable, binding.fabBadge, null)
}

Upvotes: 1

Related Questions