I am using Kotlin data class with KotlinModel like the following sample https://github.com/airbnb/epoxy/blob/master/kotlinsample/src/main/java/com/airbnb/epoxy/kotlinsample/models/ItemDataClass.kt
It doesn't provide a way to add a click listener in the class.
One option is this approach https://github.com/airbnb/epoxy/issues/525
Or you can put the listener in the constructor and have it be included in equals/hashcode
I'm trying to come up with a better general solution for dealing with listeners in all model types though, btw
I have seen that approach. How to make it work with a controller? I mean I want something like this
SampleKotlinModel(...)
.id(...)
.listener(...)
.addTo(this)
I am also trying to implement Kotlin model with data classes and had the same question. Would be really neat if we could achieve something like @NapasPayu is asking for.
@NapasPayu i'm using it this but surely there will be a better way .
data class FeedViewModel(val click: (()-> Unit)? = null,
val isVideo: Boolean = false,
val statusRes: Int? = null)
: KotlinModel(R.layout.item_feed) {
override fun bind() {
view?.apply {
setOnClickListener { click?.invoke() }
if(statusRes == null){
status_img.gone()
}else{
status_img.visible()
status_img.setImageResource(statusRes)
}
if(isVideo){
play_icon.visible()
}else{
play_icon.gone()
}
}
}
}
and here is Kotlin Model base class
abstract class KotlinModel(@LayoutRes private val layoutRes: Int) : EpoxyModel<View>() {
var view: View? = null
abstract fun bind()
override fun bind(view: View) {
this.view = view
bind()
}
override fun unbind(view: View) {
this.view = null
}
override fun getDefaultLayout() = layoutRes
}
}
and on controller side
my_profile_list.withModels {
FeedViewModel(click = {
launchIncidentDetail()
},isVideo = true).id("feed_item1").addTo(this)
}
Without annotation processing you are pretty limited in your options. You can put the listener in the primary constructor, just understand the reasoning behind DoNotHash and the workarounds, I am also working on a keyed system that could work here - https://github.com/airbnb/epoxy/pull/540
you could add an extension function like this to your EpoxyController class.
infix inline fun <V, T : EpoxyModel<V>> T with(block: T.() -> Unit) = this.apply(block).addTo(this@EpoxyController)
and then do
SampleKotlinModel(...) with {
id(...)
listener(...)
}
It's just pure kotlin, so you can do whatever you want in the bounds of that, it's not really related to epoxy at this point
Sorry for hijacking this post, I just want to ask if KotlinModel class is not actually included in the library and I have to copy it manually from the samples, or am I missing something? Thanks.
Yes, it's not directly included in the library or officially supported - it's just an example of how you could choose do write your models
"Without annotation processing you are pretty limited in your options" can you please explain what can't be achieved by only using kotlin model with annotation and what if use my model like this
data class FeedViewModel(
val isVideo: Boolean = false,
val statusRes: Int? = null)
: KotlinModel(R.layout.item_feed) {
val click: (()-> Unit)? = null // in order to prevent the hashcode/equal
to change when model bind
override fun bind() {
}
}
This is all explained in the wiki - take some time to understand all parts of how epoxy works. I wouldn't recommend using the KotlinModel class unless you are very familiar with what you are doing.
i updated the wiki about it to reflect that https://github.com/airbnb/epoxy/wiki/Kotlin-Model-Examples#custom-kotlin-model
Most helpful comment
@NapasPayu i'm using it this but surely there will be a better way .
and here is Kotlin Model base class
and on controller side