mikepenz / FastAdapter

The bullet proof, fast and easy to use adapter library, which minimizes developing time to a fraction...
https://mikepenz.dev
Apache License 2.0
3.83k stars 492 forks source link

How to get access to function of Item from ViewHolder? #1036

Closed Chimildic closed 2 years ago

Chimildic commented 2 years ago

Bind logic inside Fragment

override fun onBindMany(viewHolder: RecyclerView.ViewHolder): List<View>? {
    if (viewHolder !is BindingViewHolder<*>)
        return null

    return when (viewHolder.binding) {
        is ToolboxOrderItemBinding -> {
            (viewHolder.binding as ToolboxOrderItemBinding).run {
                listOf(
                    orderTypeShuffle,
                    orderTypeReverse,
                   // ...
                )
            }
        }
        else -> null
    }
}

I would like to incapsulate list of view inside Item. Something like this:

class ToolboxOrderItem(
    override val level: Int,
    override var model: ToolboxOrderItemModel,
    override var parent: IParentItem<*>?,
) : ModelAbstractBindingLevelItem<ToolboxOrderItemModel, ToolboxOrderItemBinding>(model),
    ISubItem<BindingViewHolder<ToolboxOrderItemBinding>> {

   // ...

    fun onBindMany(binding: ToolboxOrderItemBinding): List<View> {
        return binding.run {
            listOf(
                 //...
            )
        }
    }
}

But is there way get Item from ViewHolder? In order to call item.onBindMany(viewHolder.binding)

// fragment
override fun onBindMany(viewHolder: RecyclerView.ViewHolder): List<View>? {
    // ... ?
}

Checklist

mikepenz commented 2 years ago

Not sure on the usecase for such a setup. Seems like this is working around what the FastAdapter offers, making it obsolete?

Anyways, there's the API used internally within the FastAdapter to get the item / adapter: https://github.com/mikepenz/FastAdapter/blob/develop/fastadapter/src/main/java/com/mikepenz/fastadapter/FastAdapter.kt#L946-L984

Chimildic commented 2 years ago

No sure that understand API, because item is null in this case:

override fun onBindMany(viewHolder: RecyclerView.ViewHolder): List<View>? {
    if (viewHolder !is BindingViewHolder<*>)
        return null

    return when (viewHolder.binding) {
        is ToolboxOrderItemBinding -> {
            val binding = viewHolder.binding as ToolboxOrderItemBinding
            val item = FastAdapter.getHolderAdapterItem<ToolboxOrderItem>(viewHolder)
            return item?.onBindMany(binding)
        }
        else -> null
    }
}
mikepenz commented 2 years ago

@Chimildic well it's null if it was not yet bound by the FastAdapter. There is no other way to get the holder by the item otherwise.

Also please note that it will also be null if it is currently not visible in the RV. As the RecyclerView will re-use ViewHolders and dynamically bind and unbind the data as you scroll.

Chimildic commented 2 years ago
// item
class ToolboxOrder(
    override val level: Int,
    override var model: ToolboxOrderModel,
    override var parent: IParentItem<*>?,
) : ModelAbstractBindingLevelItem<ToolboxOrderModel, ToolboxOrderBinding>(model),
    ISubItem<BindingViewHolder<ToolboxOrderBinding>> {

    // ...

    companion object {
        fun onBindMany(binding: ToolboxOrderBinding): List<View> {
            return binding.run {
                listOf(
                    // ...
                )
            }
        }
    }
}
// fragment
override fun onBindMany(viewHolder: RecyclerView.ViewHolder): List<View>? {
    if (viewHolder !is BindingViewHolder<*>)
        return null

    return when (viewHolder.binding) {
        is ToolboxOrderBinding ->
            ToolboxOrder.onBindMany(viewHolder.binding as ToolboxOrderBinding)

        else -> null
    }
}