Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Kotlin property access syntax work for Java classes (i.e. EditText setText)?

I'm trying to switch my Android project to Kotlin. I have an EditText (a subclass of TextView) for which I want to set a hint and text programmatically. The hint works as expected. For text, though, I'm getting a type mismatch exception if I try to do it using Kotlin setter syntax:

    val test = EditText(context)

    test.setHint("hint")    // Lint message: "Use property access syntax"
    test.hint = "hint"      // ok

    test.setText("text")    // ok (no lint message)
    test.text = "text"      // Type mismatch: inferred type is kotlin.String but android.text.Editable! was expected

If we look at the declaration, we'll find identical signatures inherited from TextView:

    public final void setHint(CharSequence hint)

    public final void setText(CharSequence text)

I had an impression that x.y = z was a shortcut for x.setY(z) but apparently that impression was wrong. setText() is treated as a normal method rather than a setter, but what's the difference between these two methods that makes the compiler behave differently? The only one I can think of is that TextView has an mHint property but I don't think it might be the case.

Another thing I don't quite understand is, where does android.text.Editable come from? There is no corresponding setText(Editable) method, nor is there a public field of this type.

like image 868
SqueezyMo Avatar asked May 22 '16 11:05

SqueezyMo


People also ask

What is property access syntax in Kotlin?

Another big improvement introduced by Kotlin is the way to access properties. In Java, we access a property using the corresponding method ( setSpeed / getSpeed ). Kotlin promotes property access syntax, which is a more expressive way of accessing properties.

How do I use property in Kotlin?

Properties are an important part of any programming language. In Kotlin, we can define properties in the same way as we declare another variable. Kotlin properties can be declared either as mutable using the var keyword or as immutable using the val keyword.

What is a Kotlin property?

Variable having a class level scope (member variables) which are declared inside the class but outside the methods or functions is called as Property in Kotlin. They are declared with var keyword for a mutable one and with val keyword for a read-only/nonmutable one. The full syntax for declaring a property is.


2 Answers

When generating a synthetic property for a Java getter/setter pair Kotlin first looks for a getter. The getter is enough to create a synthetic property with a type of the getter. On the other hand the property will not be created if only a setter presents.

When a setter comes into play property creation becomes more difficult. The reason is that the getter and the setter may have different type. Moreover, the getter and/or the setter may be overridden in a subclass.

In your case the TextView class contains a getter CharSequence getText() and a setter void setText(CharSequence). If you had a variable of type TextView your code would work fine. But you have a variable of type EditText. And the EditText class contains an overridden getter Editable getText(), which means that you can get an Editable for an EditText and set an Editable to an EditText. Therefore, Kotlin reasonably creates a synthetic property text of type Editable. The String class is not Editable, that's why you cannot assign a String instance to the text property of the EditText class.

like image 143
Michael Avatar answered Oct 29 '22 03:10

Michael


To avoid type mismatch, you can use the Factory inner class of Editable class. So you can do now something like:

textview.text = Editable.Factory.getInstance().newEditable("your text")  
like image 19
souleymane sidibé Avatar answered Oct 29 '22 03:10

souleymane sidibé