一、findViewById
缺点:代码量大,繁琐
二、butterknife
缺点:组件化开发中使用不友好(注意事项:https://blog.csdn.net/yufumatou/article/details/109583839)
三、kotlin-android-extensions
优点:最简单,只需通过id即可
缺点:
1、只能支持Kotlin语言,而无法支持Java语言
2、在Recyclerview适配器中需要避免入坑
class OrderAdapter(val orderList: List<Order>) : RecyclerView.Adapter<OrderAdapter.ViewHolder>() {
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.order_item, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val order = orderList[position]
holder.itemView.tvOrderId.text = order.id
}
override fun getItemCount() = orderList.size
}
以上是错误用法,因为holder.itemView.tvOrderId反编译成java代码会看到每次都调用findViewById来获取控件,这样就失去ViewHolder无需重复获取控件的意义,这里正确写法如下:
class OrderAdapter(val orderList: List<Order>) : RecyclerView.Adapter<OrderAdapter.ViewHolder>() {
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view){
//需要在这里获取控件,防止重复findViewById
val tvOrderId: TextView = itemView.tvOrderId
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.order_item, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val order = orderList[position]
holder.tvOrderId.text = order.id
}
override fun getItemCount() = orderList.size
}
3、kotlin-android-extensions插件已被废弃
扫描二维码关注公众号,回复:
12663389 查看本文章

四、ViewBinding
1、Android studio 3.6及以上版本
2、build.gradle中如下配置(开启该配置后,创建布局文件,自动创建对于的Binding类)
android {
...
buildFeatures {
viewBinding true
}
}
3、activity中使用
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.textView.text = "Hello Word"
}
}
4、fragment中使用
class MainFragment : Fragment() {
private var mBinding: FragmentMainBinding? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
FragmentMainBinding.inflate(inflater, container, false).let{
mBinding = it
return it.root
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
mBinding?.textView.text = "Hello"
}
override fun onDestroyView() {
super.onDestroyView()
mBinding = null
}
}
5、adapter中使用
class OrderAdapter(val orderList: List<Order>) : RecyclerView.Adapter<OrderAdapter.ViewHolder>() {
inner class ViewHolder(binding: OrderItemBinding) : RecyclerView.ViewHolder(view){
val tvOrderId: TextView = binding.tvOrderId
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = OrderItemBinding(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(binding)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val order = orderList[position]
holder.tvOrderId.text = order.id
}
override fun getItemCount() = orderList.size
}
6、include中使用
(1)include添加id
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
android:id="@+id/titleBar"
layout="@layout/titlebar" />
...
</LinearLayout>
(2)使用include中控件
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.titleBar.title.text = "标题"
}
}
7、merge中使用
(1)创建merge
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp" />
</merge>
(2)使用merge
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
layout="@layout/titlebar" />
</LinearLayout>
(3)关联merge
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var titlebarBinding: TitlebarBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
//进行关联,TitleBarBinding为自动创建
titlebarBinding = TitlebarBinding.bind(binding.root)
setContentView(binding.root)
titlebarBinding.title.text = "标题"
}
}
五、DataBinding(参考DataBinding详解)
六、总结
对比这几种方式,还是kotlin-android-extensions代码更为简洁,但具体使用根据项目而定,这里主要是学会各个方式,方便维护已有项目。