• Jetpack系列 -- ViewBinding应用


    一、ViewBinding是什么?

    ViewBinding是Android开发中引入的一种新的视图绑定机制。在传统的Android开发中,我们通过调用findViewById()方法来获取布局文件中的视图对象,然后进行操作。这种方式存在一些问题,比如需要手动查找和引用视图,容易出现空指针异常,而且代码冗长。

    ViewBinding通过使用自动生成的绑定类,使视图绑定更加简单和类型安全。它利用了注解处理器,在编译时生成一个与布局文件相关联的绑定类。这个绑定类包含了布局文件中的所有视图对象,并提供了相应的getter方法,可以直接访问这些视图。

    使用ViewBinding的好处包括:

    1. 简化视图绑定:不再需要手动调用findViewById()方法,可以直接通过生成的绑定类来获取视图对象。
    2. 类型安全:生成的绑定类会根据布局文件中的视图类型自动推断返回的对象类型,避免了类型转换错误。
    3. 减少空指针异常:由于视图对象是通过绑定类获取的,不再需要手动检查null,可以减少空指针异常的风险。
    4. 提高性能:由于视图对象是在编译时生成的,不需要在运行时进行查找,可以提高应用程序的性能。

    二、启用ViewBinding

    在build.gradle(:app)

    1. android {
    2. ...
    3. viewBinding {
    4. enabled true
    5. }
    6. }

    三、使用ViewBinding

    1.在activity中使用viewBinding

    1. class MainActivity : AppCompatActivity() {
    2. lateinit var binding: ActivityMainBinding
    3. override fun onCreate(savedInstanceState: Bundle?) {
    4. super.onCreate(savedInstanceState)
    5. binding=ActivityMainBinding.inflate(layoutInflater)
    6. setContentView(R.layout.activity_main)
    7. }
    8. }

    2.在Fragment中使用viewBinding

    1. class MainFragment : Fragment() {
    2. private var _binding: FragmentMainBinding? = null
    3. private val binding get() = _binding!!
    4. override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
    5. _binding = FragmentMainBinding.inflate(inflater, container, false)
    6. return binding.root
    7. }
    8. override fun onDestroyView() {
    9. super.onDestroyView()
    10. _binding = null
    11. }
    12. }

    3.在Adapter中使用ViewBinding

    1. class FruitAdapter(val fruitList: List) : RecyclerView.Adapter() {
    2. inner class ViewHolder(binding: FruitItemBinding) : RecyclerView.ViewHolder(binding.root) {
    3. val fruitImage: ImageView = binding.fruitImage
    4. val fruitName: TextView = binding.fruitName
    5. }
    6. override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    7. val binding = FruitItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
    8. return ViewHolder(binding)
    9. }
    10. override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    11. val fruit = fruitList[position]
    12. holder.fruitImage.setImageResource(fruit.imageId)
    13. holder.fruitName.text = fruit.name
    14. }
    15. override fun getItemCount() = fruitList.size
    16. }

    4.include标签的viewBinding使用

    include标签的布局

    1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    2. android:layout_width="match_parent"
    3. android:layout_height="match_parent" >
    4. <Button
    5. android:id="@+id/back"
    6. android:layout_width="wrap_content"
    7. android:layout_height="wrap_content"
    8. android:layout_alignParentLeft="true"
    9. android:layout_centerVertical="true"
    10. android:text="Back" />
    11. <TextView
    12. android:id="@+id/title"
    13. android:layout_width="wrap_content"
    14. android:layout_height="wrap_content"
    15. android:layout_centerInParent="true"
    16. android:text="Title"
    17. android:textSize="20sp" />
    18. <Button
    19. android:id="@+id/done"
    20. android:layout_width="wrap_content"
    21. android:layout_height="wrap_content"
    22. android:layout_alignParentRight="true"
    23. android:layout_centerVertical="true"
    24. android:text="Done" />
    25. RelativeLayout>

    activity_main.xml中引入include标签的布局,一定要记得给include的布局加上id属性,不然到MainActivity中就找不到

    1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    2. android:layout_width="match_parent"
    3. android:layout_height="match_parent"
    4. android:orientation="vertical">
    5. <include
    6. android:id="@+id/titleBar"
    7. layout="@layout/titlebar" />
    8. ...
    9. LinearLayout>

    MainActivity中通过include布局的id来使用viewBinding

    1. class MainActivity : AppCompatActivity() {
    2. private lateinit var binding: ActivityMainBinding
    3. override fun onCreate(savedInstanceState: Bundle?) {
    4. super.onCreate(savedInstanceState)
    5. binding = ActivityMainBinding.inflate(layoutInflater)
    6. setContentView(binding.root)
    7. binding.titleBar.title.text = "Title"
    8. binding.titleBar.back.setOnClickListener {
    9. }
    10. binding.titleBar.done.setOnClickListener {
    11. }
    12. }
    13. }

    5.merge标签的viewBinding使用 

    merge标签的布局

    1. <merge xmlns:android="http://schemas.android.com/apk/res/android">
    2. <Button
    3. android:id="@+id/back"
    4. android:layout_width="wrap_content"
    5. android:layout_height="wrap_content"
    6. android:layout_alignParentLeft="true"
    7. android:layout_centerVertical="true"
    8. android:text="Back" />
    9. <TextView
    10. android:id="@+id/title"
    11. android:layout_width="wrap_content"
    12. android:layout_height="wrap_content"
    13. android:layout_centerInParent="true"
    14. android:text="Title"
    15. android:textSize="20sp" />
    16. <Button
    17. android:id="@+id/done"
    18. android:layout_width="wrap_content"
    19. android:layout_height="wrap_content"
    20. android:layout_alignParentRight="true"
    21. android:layout_centerVertical="true"
    22. android:text="Done" />
    23. merge>

    activity_main.xml中引入merge标签的布局,与include不同的是,在引入时去掉id属性防止崩溃:

    1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    2. android:layout_width="match_parent"
    3. android:layout_height="match_parent"
    4. android:orientation="vertical">
    5. <include
    6. layout="@layout/titlebar" />
    7. LinearLayout>

    MainActivity中通过创建两个viewBinding,一个是activity_main.xml的,另一个是我们引入的merge标签的,然后使用merge标签自动生成的viewBinding的bind方法绑定到activity_main.xml的viewBinding中。

    1. class MainActivity : AppCompatActivity() {
    2. private lateinit var binding: ActivityMainBinding
    3. private lateinit var titlebarBinding: TitlebarBinding
    4. override fun onCreate(savedInstanceState: Bundle?) {
    5. super.onCreate(savedInstanceState)
    6. binding = ActivityMainBinding.inflate(layoutInflater)
    7. titlebarBinding = TitlebarBinding.bind(binding.root)
    8. setContentView(binding.root)
    9. titlebarBinding.title.text = "Title"
    10. titlebarBinding.back.setOnClickListener {
    11. }
    12. titlebarBinding.done.setOnClickListener {
    13. }
    14. }
    15. }

  • 相关阅读:
    多年以后「PageHelper」又深深的给我上了一课
    Spire.office for Java 7.8.0
    DS链表—学生宿舍管理(双向列表容器List)
    如何解决响应结果中文乱码问题
    Git问题汇总
    【毕业设计】基于Stm32的便携体测仪(心率 体温) - 单片机 嵌入式 物联网
    Excel宏(VBA)自动化标准流程代码
    【Linux】apt update和apt upgrade
    数仓埋点体系与归因实践
    【Kingbase8数据库】flowable兼容人大金仓Kingbase8过程
  • 原文地址:https://blog.csdn.net/sziitjin/article/details/132945381