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)

我有一个印象,x.y = zx.setY(z)的捷径,但显然这个印象是错误的.setText()被视为一个普通的方法,而不是setter,但是这两个方法之间的区别是什么,使得编译器的行为不同呢?我能想到的唯一一个是TextViewmHint个属性,但我不认为可能是这样.

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.

推荐答案

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.

Kotlin相关问答推荐

将带大括号和不带大括号的Lambda值赋给@Composable函数

在Kotlin中,我是否可以访问已知的WHEN子句值?

如何在Android应用判断上运行多个查询

如何在不基于数据 map 的情况下将图例添加到lets plot kotlin

Kotlin Poet 的导入不明确

在 kotlin 原始字符串中转义三重引号

在 Kotlin 协程中切换 IO 和 UI 的正确方法是什么?

即使 Kotlin 的 `Map` 不是 `Iterable`,它如何以及为什么是可迭代的?

AIDL 中的 Parcelize 注释:Incompatible types: Object cannot be converted to MyCustomObject

java - 如何将函数作为参数从java传递给kotlin方法?

如何有效地填充 Gradle Kotlin DSL 中的额外属性?

什么是 .kotlin_builtins 文件,我可以从我的 uberjars 中省略它们吗?

如何从定义它们的类外部调用扩展方法?

Jetpack Compose – LazyColumn 不重组

如果作为 RxJava Observable 提供,Kotlin 密封类子类需要强制转换为基类

Kotlin 警告:Conditional branch result of type ... is implicity cast of Any?

spring.config.location 在 Spring Boot 2.0.0 M6 上不起作用

如何根据ArrayList的对象属性值从中获取最小/最大值?

尾随 lambda 语法(Kotlin)的目的是什么?

如何将 Kotlin 的 `with` 表达式用于可空类型