Android Kotlin开发中findViewById()与直接使用ID的区别是什么?
两种点击监听写法的区别详解
嘿,完全不用不好意思!刚入坑Android和Kotlin的时候,这些看似相似的写法确实容易让人懵,我来给你把这两者的区别讲得明明白白~
1. 传统写法:findViewById<Button>(R.id.done_button).setOnClickListener { changeNickname() }
这是Android早期(甚至现在也还能看到)的标准视图查找方式:
- 核心逻辑:通过
findViewById方法,传入布局中定义的视图ID(R.id.done_button),找到对应的Button实例。<Button>是泛型声明,用来指定返回的视图类型,避免后续手动强转,让代码更安全。 - 特点:写法直观,但代码冗余——如果要操作多个视图,就得重复写一堆
findViewById;而且如果ID写错、视图不存在或者类型不匹配,可能会在运行时抛出异常。
2. 语法糖写法:done_button.setOnClickListener { changeNickname() }
这是曾经很流行的**Kotlin Android扩展(Kotlin Android Extensions)**提供的简化写法:
- 核心逻辑:编译器会在后台自动帮你生成对应视图ID的变量,你直接用ID作为变量名就能访问视图,省去了手动调用
findViewById的步骤,写起来特别简洁。 - 注意点:这种写法现在已经被官方弃用了!因为它存在不少隐患:比如布局中没有对应ID时,编译阶段可能不会报错,到运行时才会崩溃;在多布局切换(比如Fragment切换布局)的场景下,还容易出现空指针问题。
现在的最佳实践
官方现在更推荐使用**视图绑定(View Binding)**来替代上面两种写法,它兼顾了简洁性和安全性:
- 启用View Binding后,编译器会为每个布局文件生成对应的绑定类(比如布局是
activity_main.xml,就会生成ActivityMainBinding类)。 - 使用时只需要初始化绑定类,然后通过绑定对象直接访问视图:
这种写法既不用重复写private lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) binding.doneButton.setOnClickListener { changeNickname() } }findViewById,又能在编译阶段就检查出视图是否存在、类型是否匹配,大大降低了运行时崩溃的概率。
内容的提问来源于stack exchange,提问作者anas gharbi
相关产品推荐
相关产品推荐

