Home > OS >  Android Studio Kotlin Boolean.Companion problem
Android Studio Kotlin Boolean.Companion problem

Time:08-26

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.

ViewHolders are special objects that get reused to display different data items - and by definition there's usually more data items than there are ViewHolders (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 Views you're using in the VH, like a TextView and a Checkbox, so you can do things like

holder.taskTextView.text = item.getTask()

  • Related