Kotlin属性访问语法如何用于Java类(即EditText setText)?

时间:2016-05-22 11:59:28

标签: android android-edittext kotlin

我正在尝试将我的Android项目切换到Kotlin。我有一个EditTextTextView的子类),我想以编程方式设置提示和文本。提示按预期工作。但是对于文本,如果我尝试使用Kotlin setter语法,我会遇到类型不匹配异常:

    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

如果我们查看声明,我们会发现从TextView继承的相同签名:

    public final void setHint(CharSequence hint)

    public final void setText(CharSequence text)

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

我不太明白的另一件事是android.text.Editable来自何处?没有相应的setText(Editable)方法,也没有此类型的公共字段。

感谢。

4 个答案:

答案 0 :(得分:43)

为Java getter / setter对生成合成属性时,Kotlin首先寻找getter。 getter足以创建一个具有getter类型的合成属性。另一方面,如果只有一个setter出现,则不会创建该属性。

当一个二传手进场时,属性创造变得更加困难。原因是吸气剂和定位器可能具有不同的类型。此外,可以在子类中重写getter和/或setter。

在您的情况下,TextView类包含一个getter CharSequence getText()和一个setter void setText(CharSequence)。如果你有一个TextView类型的变量,你的代码就可以了。但是你有一个EditText类型的变量。 EditText类包含重写的getter Editable getText(),这意味着您可以为Editable获取EditText并将Editable设置为EditText }}。因此,Kotlin合理地创建了text类型的合成属性EditableString类不是Editable,这就是为什么您无法将String实例分配给text类的EditText属性的原因。

答案 1 :(得分:9)

为避免类型不匹配,可以使用Editable类的Factory内部类。 所以你现在可以这样做:

textview.text = Editable.Factory.getInstance().newEditable("your text")  

答案 2 :(得分:4)

node_modules来自getText()。在我看来,Kotlin的android.text.Editable分辨率是两个步骤。

  1. 编译器尝试查找obj.text = value属性或Java方法text,从中推断出属性类型
  2. 对于推断的属性类型,编译器会尝试查找相应的属性setter或Java方法getText
  3. 由于1.推断类型为setText(PropertyType value)Editable失败且出现editText.text = "value"错误。

答案 3 :(得分:4)

或者,您可以编写扩展名:

fun String.toEditable(): Editable =  Editable.Factory.getInstance().newEditable(this)

您可以按以下方式使用它:

mEditText.text = myString.toEditable()