3

I have created extension method:

@Suppress("UNCHECKED_CAST")
operator fun <T : View> View.get(@IdRes id:Int): T  =
        this.findViewById(id) as T

Main usage of this method:

class A {
    lateinit var text: TextView

    fun init(view:View) {
        text = view[R.id.text]
    }
}

This works perfectly, but when I try use it without variable:

fun test() {
    view[R.id.text].visibility = View.GONE // error
}

Error:

Type inference failed: Not enough information to infer parameter T in 
operator fun <T : View> View.get(id: Int): T
Please specify it explicitly.

If I write the analog code in java, methods of class View available without direct specification of View type.

Is it possible in kotlin? Maybe do some changes in signature of generic type somehow?

curioushikhov
  • 2,461
  • 2
  • 30
  • 44
  • I guess Java just defaults to `T`'s bound if it is valid, but Kotlin doesn't. – Jorn Vernee Aug 04 '17 at 14:01
  • I have found workaround view.get(R.id.text) = View.GONE but in this case I prefer view.findViewById(R.id.text) because brackets adds a lot of noise to parse statements while reading. – curioushikhov Aug 04 '17 at 14:10
  • With Kotlin you can easily get rid of `findViewById`: https://kotlinlang.org/docs/tutorials/android-plugin.html – Miha_x64 Aug 05 '17 at 09:09
  • For now for me it is useless, because it doesn't support fragments, you can't control when to bind view to fields like Butterknife do, and it hilaruisly fails for dynamic layouts. – curioushikhov Aug 05 '17 at 09:44

1 Answers1

0

It is not possible to specify the generics type on the get operator, and it is also not possible to the compiler to infer what type does that get should return.

You can call the get function as an ordinary function view.get<TextView>(R.id.text), without using the operator overloading convention.

To achieve the desired functionality, you can use the Kotlin Android Extensions as suggested by @Miha_x64, without the need to use the findViewByIdmethod.

Diego Malone
  • 1,044
  • 9
  • 25