I'm using the Epoxy library
on Android
.
What I'm curious about is why the parameter
of the lambda expression
doesn't get an error when the type doesn't match.
The listener
is a lambda expression
that takes an Int type
as a parameter.
But listener(addDetailClicked)
works normally.
Shouldn't it be listener(Int)
? or listener({ i -> addDetailClicked(i) })
.
Actually, I don't know why it works even after I write the code.
How is this possible?
Model
@EpoxyModelClass(layout = R.layout.item_routine)
abstract class EpoxyRoutineModel() : EpoxyModelWithHolder<EpoxyRoutineModel.Holder>() {
@EpoxyAttribute
var workout: String = "see"
@EpoxyAttribute
var curPos: Int = 0
@EpoxyAttribute
lateinit var listener: (Int) -> Unit // this
override fun bind(holder: Holder) {
holder.workout.text = workout
holder.add_btn.setOnClickListener {
listener(curPos)
}
}
}
Controller
class RoutineItemController(
private val addDetailClicked: (Int) -> Unit)
: EpoxyController() {
private var routineItem : List<RoutineItem>? = emptyList()
override fun buildModels() {
var i:Int =0
routineItem?.forEach {
when(it) {
is RoutineItem.RoutineModel ->
EpoxyRoutineModel_()
.id(i )
.curPos(i )
.workout("d")
.listener(addDetailClicked) // why? listener(Int) or listener({ i -> addDetailClicked(i) })
.addTo(this)
}
}
}
}
Fragment
class WriteRoutineFragment : Fragment() {
private var _binding : FragmentWriteRoutineBinding? = null
private val binding get() = _binding!!
private lateinit var epoxyController : RoutineItemController
private val vm : WriteRoutineViewModel by viewModels { WriteRoutineViewModelFactory() }
override fun onCreateView(inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?): View? {
_binding = FragmentWriteRoutineBinding.inflate(inflater, container, false)
epoxyController = RoutineItemController(::addDetail)
binding.rv.adapter = epoxyController.adapter
binding.rv.itemAnimator = null
return binding.root
}
private fun addDetail(pos: Int) {
vm.addDetail2(pos)
}
}
CodePudding user response:
I believe you missed the fact that EpoxyRoutineModel_
contains setters for data types found in EpoxyRoutineModel
. For example, EpoxyRoutineModel.curPos
is of type Int
, so EpoxyRoutineModel_.curPos()
is a function declared as:
fun curPos(Int): EpoxyRoutineModel_
(or similar)
Similarly, EpoxyRoutineModel.listener
is of type (Int) -> Unit
, so EpoxyRoutineModel_.listener()
is declared as:
fun listener((Int) -> Unit): EpoxyRoutineModel_
So listener()
is a function that receives another function (which itself receives Int
). So we can provide addDetailClicked
there.