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的简单用法:

扫描二维码关注公众号,回复: 16182902 查看本文章

首先,将viewBinding导入到项目中

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

android {
    ...
    buildFeatures {
        viewBinding true
    }
}

在activity中使用viewBinding

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

class MainActivity : AppCompatActivity() {
    lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding=ActivityMainBinding.inflate(layoutInflater)
        setContentView(R.layout.activity_main)
    }
}

在Fragment中使用viewBinding

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

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
    }

}

最核心的逻辑仍然是调用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。

class FruitAdapter(val fruitList: List<Fruit>) : RecyclerView.Adapter<FruitAdapter.ViewHolder>() {

    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

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

在布局文件中使用viewBinding

include标签的viewBinding使用

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

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@+id/back"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:text="Back" />

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Title"
        android:textSize="20sp" />

    <Button
        android:id="@+id/done"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:text="Done" />

</RelativeLayout>

那么在activity_main.xml布局文件中引入布局可以这么写:

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

一定要记得给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标签的viewBinding使用 

使用merge标签时,假设我们引入的布局文件如下:

<merge xmlns:android="http://schemas.android.com/apk/res/android">

    <Button
        android:id="@+id/back"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:text="Back" />

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Title"
        android:textSize="20sp" />

    <Button
        android:id="@+id/done"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:text="Done" />

</merge>

 与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
        layout="@layout/titlebar" />

</LinearLayout>

 然后修改MainActivity中的代码如下:

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

}

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

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

猜你喜欢

转载自blog.csdn.net/liny70858/article/details/127253151
今日推荐