当前位置:   article > 正文

Android中viewBinding的简单用法_android viewbinding

android viewbinding

初级菜鸟,正在向中级菜鸟努力!

刚刚接触Android开发,有好多东西都不太懂,又喜欢忘东西,干脆写博客记录一下吧。

目录

在activity中使用viewBinding

在Fragment中使用viewBinding

在Adapter中使用ViewBinding

在布局文件中使用viewBinding

include标签的viewBinding使用

merge标签的viewBinding使用 


kotlin-android-extensions插件已被废弃,现在推荐使用ViewBinding来进行替代。我的理解是,viewBinding是我们在完成创建一个layout的xml文件时自动生成的一个绑定类,该类以创建的xml文件名+Binding来命名且采用驼峰命名法,如果xml文件名是activity_main.xml,那么绑定类的名称就是ActivityMainBinding,我们可以通过实例化这个绑定类来操纵xml布局文件中的控件属性。以下是viewBinding的简单用法:

首先,将viewBinding导入到项目中

在Module级别的build.gradle中写入如下代码:

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

在activity中使用viewBinding

我们使用MainActivity为例,使用viewBinding来引入activity_main.xml这个布局,实例化这个绑定类为binding,然后就可以使用其中的控件了,这里我们将根布局传入setContentView中代替原来的R.layout.activity_main。我们可以先全局声明一下,在oncreate方法中进行赋值,这样就不用在MainActivity中的其他方法中使用view Binding时重新创建实例了。

  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. }

Fragment中使用viewBinding

假设我们有一个布局文件叫fragment_main.xml,并且想在MainFragment中去显示这个布局。因为kotlin的判空机制,所以代码有些怪怪的。

  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. }

最核心的逻辑仍然是调用FragmentMainBinding的inflate()函数去加载fragment_main.xml布局文件,但由于这是在Fragment当中,所以使用了3个参数的inflate()函数重载,这和我们平时在Fragment中去加载布局文件的方式如出一辙。而在onCreateView()函数中加载的布局,在与其对应的onDestroyView()函数中对binding变量置空,以保证binding变量的有效生命周期是在onCreateView()函数和onDestroyView()函数之间。

在Adapter中使用ViewBinding

这是《第一行代码》中的适配器部分,使用viewBinding改造后的样子。首先改造ViewHolder,让其构造函数接收FruitItemBinding这个参数。但是注意,ViewHolder的父类RecyclerView.ViewHolder它只会接收View类型的参数,因此我们需要调用binding.root获得fruit_item.xml中根元素的实例传给RecyclerView.ViewHolder。

  1. class FruitAdapter(val fruitList: List<Fruit>) : RecyclerView.Adapter<FruitAdapter.ViewHolder>() {
  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

主要的改动在ViewHolder和onCreateViewHolder中,其他的 部分并没有改变!

在布局文件中使用viewBinding

include标签的viewBinding使用

假设我们引入的布局如下:

  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布局文件中引入布局可以这么写:

  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>

一定要记得给include的布局加上id属性,不然到MainActivity中就找不到了!!

最后在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. }

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>

 与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中的代码如下:

  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. }

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

本文参考了郭神的kotlin-android-extensions插件也被废弃了?扶我起来

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/319898
推荐阅读
相关标签
  

闽ICP备14008679号