mikepenz / MaterialDrawer

The flexible, easy to use, all in one drawer library for your Android project. Now brand new with material 2 design.
https://mikepenz.dev
Apache License 2.0
11.67k stars 2.05k forks source link

Clickable BadgeStyle #2760

Closed virovinrom closed 2 years ago

virovinrom commented 2 years ago

Hello, is it possible to make somehow BadgeStyle clickable?

mikepenz commented 2 years ago

@virovinrom could you please elaborate more?

BadgeStyle has a different color if pressed: https://github.com/mikepenz/MaterialDrawer/blob/develop/materialdrawer/src/main/java/com/mikepenz/materialdrawer/holder/BadgeStyle.kt

also the text style is allowed to be a ColorStateList where pressed could also be handled

virovinrom commented 2 years ago

How can I set some ItemClickListener on BadgeStyle?

mikepenz commented 2 years ago

thank you for adding more details on your question.

This is not possible with the default item.

you'd have to implement your own custom drawer item or expand on one of the existing items to add a listener to it.

virovinrom commented 2 years ago

Sorry, one more question, I need to change for example PrimaryDrawerItem or AbstractBadgeableDrawerItem and not BadgeStyle ? I tied implement listener to my custom BadgeStyle and it didn't work.

mikepenz commented 2 years ago

You could for example try something like:

open class CustomPrimaryDrawerItem : AbstractBadgeableDrawerItem<CustomPrimaryDrawerItem>() {

    open var onBadgeClickListener: ((v: View?, item: IDrawerItem<*>) -> Unit)? = null

    override fun bindView(holder: ViewHolder, payloads: List<Any>) {
        super.bindView(holder, payloads)

        holder.badge.setOnClickListener {
            onBadgeClickListener?.invoke(it, this@CustomPrimaryDrawerItem)
        }
    }
}

There are surely more efficient way (this will attach a new listener each time bindView is called), but this should be fine for normal drawers without hundreds of hundreds of items.

mikepenz commented 2 years ago

Alternative a bit more efficient for longer lists

open class CustomPrimaryDrawerItem : AbstractBadgeableDrawerItem<CustomPrimaryDrawerItem>() {
    open class ViewHolder(view: View) : BaseViewHolder(view) {
        val badge: TextView = view.findViewById(R.id.material_drawer_badge)
    }
}
binding.slider.adapter.addClickListener({ vh: CustomPrimaryDrawerItem.ViewHolder -> vh.badge }) { v: View, position: Int, fastAdapter: FastAdapter<IDrawerItem<*>>, item: IDrawerItem<*> ->  
            // to what you'd like to achieve
}
virovinrom commented 2 years ago

Much obliged for your help, but I'm encounter with some additional problems in your examples. In first example he can't see bindView, and holder.badge can't be available in the same module only. But the second one, no errors, but no catch the click (.

mikepenz commented 2 years ago

@virovinrom oh for that you'd also need to expose the badge via the viewholder

open class CustomPrimaryDrawerItem : AbstractBadgeableDrawerItem<CustomPrimaryDrawerItem>() {

    open var onBadgeClickListener: ((v: View?, item: IDrawerItem<*>) -> Unit)? = null

    override fun bindView(holder: AbstractBadgeableDrawerItem.ViewHolder, payloads: List<Any>) {
        super.bindView(holder, payloads)

        holder.itemView.findViewById<View>(R.id.material_drawer_badge).setOnClickListener {
            onBadgeClickListener?.invoke(it, this@CustomPrimaryDrawerItem)
        }
    }
}
virovinrom commented 2 years ago

It works, A huge thank you.