How to inject lambda(or interface) at runtime with hilt

Viewed 332

I'm using hilt with MVVM, RecyclerView

I wanna inject a lambda into the Adapter for receiving clickListeners from child views, but with @Module, I cannot create lambda at runtime.

[Snippets below]

// Lambda Listener
class CustomAdapter @Inject constructor(private val listener: (clickedItem: Object) -> Unit) {
    override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
        holder.itemView.setOnClickListener {
            listener.invoke(clickedItem)
        }
    }
}

Is there a way to inject lambda or interface at runtime?

1 Answers

Not sure if this is the best option, but you can use AssistedInjection.

Firstly, you need to create an interface with the AssistedFactory annotation

@AssistedFactory
interface Factory {
    fun create(
        listener: (keyName: String) -> Unit
    ): CustomAdapter
}

Secondly: Replace @Inject with @AssistedInject in your adapter and add your listener in the constructor with the @Assisted annotation

class CustomAdapter @AssistedInject constructor(
    @Assisted private val listener: (keyName: String) -> Unit
)

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
    CustomViewHolder(CustomViewHolderBinding.inflate(....), listener)

Finally, in your fragment/activity, you need to inject the factory instead of your adapter, and use it to create the adapter

@Inject
lateinit var customAdapterFactory: CustomAdapter.Factory

val listener = (keyName: String) -> Unit = { keyName ->
    ......
}
val customAdapter = customAdapterFactory.create(listener)
Related