Jetpack之ViewBinding

ViewBinding 的作用:代替findViewById,还可以保证空安全和类型安全。
基本原理:会为每一个布局xml文件生成一个视图绑定类,类名称是布局文件名转化为UpperCamelCase + Binding。如布局文件为activity_main,那么将会生成一个类,类名为ActivityMainBinding。通过生成对象根节点对象就可以找到对应的Id。

基本用法:
build.gradle添加如下配置

android {
    ...
    viewBinding {
        enabled = true
    }
} 

对于不需要生成绑定类的布局xml文件,在根节点添加下面的属性tools:viewBindingIgnore="true"

在Activity中使用

布局文件

<-- activity_main.xml -->

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/btn"
        android:layout_marginTop="20dp"
        android:textSize="20sp"
        android:text="hello view"
        android:gravity="center"/>
androidx.constraintlayout.widget.ConstraintLayout>

程序中:

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 实例化绑定视图
        binding = ActivityMainBinding.inflate(layoutInflater)
        // 获取根节点的引用
        val view = binding.root
        // 让根节点视图成为获得视图
        setContentView(view)
        // 引用视图上的控件
        binding.btn.setOnClickListener {
            binding.tv.text = "Binding View"
        }
    }
}

在Fragment中使用

主布局里面的fragment标签必须要有id。Fragment中的代码如下:

class TestFragment:Fragment() {
    private var _binding : TestFrameBinding? = null
    private val binding get() = _binding!!
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = TestFrameBinding.inflate(inflater,container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.frameBtn.setOnClickListener {
            binding.frameBtn.text = "clicked"
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        // Fragment的存活时间比View长,在其onDestroy()方法中清除对绑定类实例的所有引用
        _binding = null
    }
}

RecyclerView中

class TestAdapter(list: List<String>) : RecyclerView.Adapter<TestAdapter.ViewHolder>() {
    private var mList: List<String> = list

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        // 需在此初始化以获得父类容器
        val binding = ItemTestBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return ViewHolder(binding)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.tvItem.text = "Adapter"
    }

    override fun getItemCount() = mList.size

    // 传递Binding对象
    class ViewHolder(binding: ItemTestBinding) : RecyclerView.ViewHolder(binding.root) {
        var tvItem: TextView = binding.tvItem
    }
} 

你可能感兴趣的:(android,kotlin,java)