Reputation: 143
I would like to know if it's possible to populate multiple fields in one line in Kotlin (just for cleaner code)
My Code:
val evh = ExampleViewHolder(binding.root)
evh.mImageView = binding.myImageView
evh.mTextView1 = binding.text1
evh.mTextView2 = binding.text2
I would like to achieve something like this:
(evh.mImageView, evh.mTextView1, evh.mTextView2) = (binding.myImageView, binding.text1, binding.text2)
Is this somewhat possible?
Upvotes: 3
Views: 1427
Reputation: 788
You could also pass views as arguments to ExampleViewHolder
, like this:
class ExampleViewHolder(
val rootView: View, val imageView: ImageView,
val textView1: TextView, val textView2: TextView
) : RecyclerView.ViewHolder(rootView) {...}
And then instantiate the ViewHolder using the apply
scope function:
val viewHolder = binding.run {
ExampleViewHolder(root, myImageView, text1, text2)
}
Upvotes: 2
Reputation: 2534
If an object has already been created, to change several fields you can use scope function "run", like:
evh.run {
mImageView = binding.myImageView
mTextView1 = binding.text1
mTextView2 = binding.text2
}
Upvotes: 1
Reputation: 3232
is this somewhat possible?
No, you can't set properties* in such a way in Kotlin.
If you'd like to initialize or change values on some properties in a cleaner way, you can use one of the scope functions:
The Kotlin standard library contains several functions whose sole purpose is to execute a block of code within the context of an object. When you call such a function on an object with a lambda expression provided, it forms a temporary scope. In this scope, you can access the object without its name. Such functions are called scope functions. There are five of them:
let
,run
,with
,apply
, andalso
.
In this particular case it seems like apply
is the best fit:
val evh = ExampleViewHolder(binding.root).apply {
mImageView = binding.myImageView
mTextView1 = binding.text1
mTextView2 = binding.text2
}
*note that similar inline syntax is valid in Kotlin and it's used in destructing declarations:
val (first, second) = listOf("firstValue", "secondValue")
Upvotes: 5
Reputation: 1232
I found this post which says it's possible if you put all views in a data class:
data class ExampleViewHolder(val mImageView: ImageView, val mTextView: TextView, val mTextView2: TextView, val binding: Binding) : RecyclerView.ViewHolder(binding.root)
and then do something like this:
val (mImageView, mTextView1, mTextView2, binding) = ExampleViewHolder(binding.myImageView, binding.text1, binding.text2, binding)
Alternatively you can always put semi-columns in between assignments to one-line it, but it does not get more readable imo:
evh.mImageView = binding.myImageView; evh.mTextView1 = binding.text1; evh.mTextView2 = binding.text2
I would just assign the fields inside your ExampleViewHolder
:
class ExampleViewHolder(binding: Binding) : RecyclerView.ViewHolder(binding.root) {
val mImageView = binding.myImageView
val mTextView = binding.text1
val mTextView2 = binding.text2
}
Or even let the ExampleViewHolder
do the binding:
class ExampleViewHolder(val binding: Binding) : RecyclerView.ViewHolder(binding.root) {
fun bindTo(item: Any) {
binding.myImageView.visibility = View.GONE
}
}
Upvotes: 1