原生页面的开发有一个让人头疼的地方:页面中控件非常多,堆砌了大量的控件声明与控件绑定代码。很明显,这属于我们想要避免的重复劳动。
而正好,Kotlin给我们提供了一个解决方法,kotlin-android-extensions,在app/build.gradle中加入下面两句即可:
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
引入了kotlin-android-extensions后,控件的使用就变得非常简洁了,在代码中直接使用xml中定义的控件名即可。
接下来要思考的问题是,为什么可以直接使用控件名去操作控件,而不用再显式地使用findViewById。
我们可以反编译Kotlin代码,查看其对应的Java代码来一探究竟:
首先在Android Studio中,点击顶部的Tools -> Kotlin,然后选择Show Kotlin Bytecode,这样在右侧就打开了Koltin代码对应的字节码,接下来,点击字节码界面左上方的Decompile,就得到了Kotlin代码对应的Java代码。
可以看到,et_account控件操作对应的代码是:
我们再看一下这个findCachedViewById方法:
可以看到,在这个方法里有一个名为findViewCache的HashMap,用来缓存每次找到的View,避免每次对View进行操作时都重新调用findViewById方法,是的,在这里,仍然是通过findViewById去获取控件的,而且每个控件的第一次使用都会调用findViewById方法,后续的使用可以在findViewCache中去获取。
另外一个需要注意的地方是,在Fragment中使用时,需要注意不能在onCreateView中直接使用控件,否则会crash,应该在onViewCreated中去使用,具体的原因如下:
可以看到,fragment对应的findCachedViewById方法与activity对应的有所不同,它需要先调用getView方法,然后再通过getView返回的值去findViewById,那么getView方法的返回值其实是mView,也就是fragment的根view:
继续看一下mView的赋值时机:
可以看到mView其实就是onCreateView的返回值,所以我们不能在onCreateView中去直接操作控件。