ViewBinding是Android开发中引入的一种新的视图绑定机制。在传统的Android开发中,我们通过调用findViewById()
方法来获取布局文件中的视图对象,然后进行操作。这种方式存在一些问题,比如需要手动查找和引用视图,容易出现空指针异常,而且代码冗长。
ViewBinding通过使用自动生成的绑定类,使视图绑定更加简单和类型安全。它利用了注解处理器,在编译时生成一个与布局文件相关联的绑定类。这个绑定类包含了布局文件中的所有视图对象,并提供了相应的getter方法,可以直接访问这些视图。
使用ViewBinding的好处包括:
findViewById()
方法,可以直接通过生成的绑定类来获取视图对象。在build.gradle(:app)
android {
...
viewBinding {
enabled true
}
}
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding=ActivityMainBinding.inflate(layoutInflater)
setContentView(R.layout.activity_main)
}
}
class MainFragment : Fragment() {
private var _binding: FragmentMainBinding? = null
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
_binding = FragmentMainBinding.inflate(inflater, container, false)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
class FruitAdapter(val fruitList: List) : RecyclerView.Adapter() {
inner class ViewHolder(binding: FruitItemBinding) : RecyclerView.ViewHolder(binding.root) {
val fruitImage: ImageView = binding.fruitImage
val fruitName: TextView = binding.fruitName
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = FruitItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(binding)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val fruit = fruitList[position]
holder.fruitImage.setImageResource(fruit.imageId)
holder.fruitName.text = fruit.name
}
override fun getItemCount() = fruitList.size
}
include标签的布局
activity_main.xml中引入include标签的布局,一定要记得给include的布局加上id属性,不然到MainActivity中就找不到
...
MainActivity中通过include布局的id来使用viewBinding
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 = "Title"
binding.titleBar.back.setOnClickListener {
}
binding.titleBar.done.setOnClickListener {
}
}
}
merge标签的布局
activity_main.xml中引入merge标签的布局,与include不同的是,在引入时去掉id属性防止崩溃:
MainActivity中通过创建两个viewBinding,一个是activity_main.xml的,另一个是我们引入的merge标签的,然后使用merge标签自动生成的viewBinding的bind方法绑定到activity_main.xml的viewBinding中。
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.bind(binding.root)
setContentView(binding.root)
titlebarBinding.title.text = "Title"
titlebarBinding.back.setOnClickListener {
}
titlebarBinding.done.setOnClickListener {
}
}
}