In my code i want to execute holder.task.setChecked() command with item.getStatus()) as a parameter.
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = data[position]
holder.task.text = item.getTask()
holder.task.setChecked(item.getStatus())
}
The problem is that setChecked requires type Boolean, but from getStatus function i get Boolean.Companion in return.
class Model(itemView: View) : RecyclerView.ViewHolder(itemView) {
private var id = Int
private var status = Boolean
private var task = String
fun getStatus(): Boolean.Companion {
return status
}
When i try to change the return type of this function, i get thrown with an error.
Been thinking for a while about how to change the types to be equal, but i cannot seem to find the solution.
To be clear, setChecked function is a default function which im executing on Checkbox object
CodePudding user response:
The setChecked
function requires a Boolean
param, but the return type of getStatus
is Boolean.Companion
. This is because you have defined the status
field as of Boolean.Companion
type.
To fix this, you may define status
as a normal class level field and either assign a default value, or provide a constructor to initialize the value appropriately.
private var status: Boolean = false // or true, depending on the default value that suits here
Then you can change the getStatus
function to return a Boolean
type instead of Boolean.Companion
fun getStatus(): Boolean {
return status
}
and then use it to call holder.task.setChecked(item.getStatus())
.
CodePudding user response:
Your example code is very unusual, and I'm not sure you actually meant to do what you're doing here.
This for example
private var id = Int
doesn't hold an Int
. id
is not a number. It's actually the companion object for the Int
class, which in this case holds the constants MAX_VALUE
, MIN_VALUE
, SIZE_BYTES
and SIZE_BITS
. Usually you'd access these directly on the Int
class, like Int.MAX_VALUE
- when you do that you're actually accessing them on the companion object, which is why assigning the value Int
to a variable gives you that companion object.
So the same goes for var status = Boolean
- it's Boolean
's companion object. And that's why your function has to return Boolean.Companion
, because it's returning status
, and that's what status
is. It's not a boolean value of true or false.
There may be reasons why you'd want to do this - it's very unlikely though, and the way you're trying to use this (wanting a Boolean
from getStatus
) suggests that this is a mistake, and you're not familiar with the language. I'd really recommend running through the basic intro stuff to get a feel for how you define variables and their types, but this is probably what you wanted:
class Model(itemView: View) : RecyclerView.ViewHolder(itemView) {
private var id: Int = -1
private var status: Boolean = false
private var task: String = ""
fun getStatus(): Boolean {
return status
}
}
I've added default values to each because you have to initialise them to something - if you have an init
block where that happens, you can omit the values. If you're assigning them right there, you can omit the types too (e.g. var id = -1
) unless you need to be more specific than the value is (e.g. if you want it to be a nullable Int?
type).
You could also put these values in the constructor:
class Model(
itemView: View,
private var id: Int,
private var status: Boolean,
private var task: String
)
which would require the caller to provide some initial values. It depends what you want!
If you wanted, you could also replace the getter function by doing this:
var status: Boolean = false
private set
which makes the status
property public, but read-only from the outside.
And just FYI, your Model
class looks like your data for your RecyclerView
's Adapter - it should not be a ViewHolder
, those are completely separate things. Just use a basic class for your Model
(or even better, a data class
) and use that in your data list.
ViewHolder
s are special objects that get reused to display different data items - and by definition there's usually more data items than there are ViewHolder
s (that's the whole point of a RecyclerView
- it recycles them). You shouldn't be keeping them in a list, or storing individual items' state in them.
Keep your data items in a list, fetch the one at position
in onBindViewHolder
, then display it in the ViewHolder
you're provided with. What you have right now isn't going to work, so you'll need to look at a tutorial for setting one up, e.g. this one from the docs. You need to store references to the View
s you're using in the VH, like a TextView
and a Checkbox
, so you can do things like
holder.taskTextView.text = item.getTask()