why must i delay the badge attach process?

70 views Asked by At

I cannot find a way to attach a badge to new layout objects. with BadgeDrawable.create,

The badges work when the corresponding object is present in the layout xml, but they are not displayed for objects added programmatically in onCreateView or onViewCreated. This happens also for the tabs of a tabLayout, for example:

val tab = binding.tabLayout.newTab()
tab.text = if (group == "") "(default)" else group
binding.tabLayout.addTab(tab)
val badge = BadgeDrawable.create(context!!)
BadgeUtils.attachBadgeDrawable(badge, tab.view, null)

The xlm of the layout is this:

<?xml version="1.0" encoding="utf-8"?>
<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="match_parent"
    android:layout_height="match_parent"
    tools:context=".fragments.sale.SaleFragment">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="409dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:contentDescription="test"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/constraintLayout" />

</androidx.constraintlayout.widget.ConstraintLayout>

The same happens if the object exists but is initially invisible and set to visible in OnCreateView or onViewCreated: I can add a badge to it only if I wait for, let's say, a second!

My only solution up to now is to wait, lets say for a second, like this:

                Timer().schedule(object: TimerTask() {
                    override fun run() {
                        BadgeUtils.attachBadgeDrawable(badge, binding.tabLayout.getTabAt(0)!!.view, null)
                    }
                }, 1000)

It works, but could depend on the speed of the device. Is there a better solution?

1

There are 1 answers

0
Massimiliano Carosi On

I figured out i need a listener on the layout process, i solved using something like this:

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