安卓ViewBinding与RecyclerView Adapt

作者: Kepler_II | 来源:发表于2021-02-22 17:55 被阅读0次

    1. 视图绑定ViewBinding与数据绑定DataBinding

    ViewBinding库会为每个xxx_layout.xml文件生成一个XxxLayoutBinding.java文件(除非声明了tools:viewBindingIgnore="true"),此类文件的成员变量包含了xml中所有声明了android:id的控件,与DataBinding不同的是,它对原有xml文件不具有侵入性,而DataBinding需要用<layout>标签包裹原布局,因此,如果你不想引入数据绑定,但又想简化findViewById这类模板代码,采用ViewBinding再好不过。

    本文不讨论如何在Activity和Fragment中使用ViewBinding,只讨论在RecyclerView Adapter中的使用

    2. 启用视图绑定

    // 文件名 build.gradle (:app)
    android {
        ...
        buildFeatures {
                viewBinding = true
            }
    }
    

    3. 封装Adapter

    // 文件名 CommonRvAdapter.kt
    /**
     * @description: recyclerView的Adapter的简单封装, 仅针对单类型viewType
     *
     * @param E: 列表数据实体类
     * @param V: item的xml文件对应的Binding类
     **/
    abstract class CommonRvAdapter<E : Any, V : ViewBinding> : RecyclerView.Adapter<CommonRvHolder<V>>() {
        /**
         * 数据源
         */
        open var data: MutableList<E> = mutableListOf()
            set(value) {
                field = value
                notifyItemRangeChanged(0, value.size)
            }
        // 为什么不把这个方法也封装起来? 因为不想使用反射~
        abstract override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CommonRvHolder<V>
        
        override fun getItemCount(): Int = data.size
        
        override fun onBindViewHolder(holder: CommonRvHolder<V>, position: Int) {
            onBindViewHolder(holder, holder.adapterPosition, holder.binding, data[holder.adapterPosition])
        }
        
        abstract fun onBindViewHolder(holder: CommonRvHolder<V>, position: Int, binding: V, bean: E)
    }
    
    open class CommonRvHolder<V : ViewBinding>(val binding: V) : RecyclerView.ViewHolder(binding.root) {
    
    }
    

    4. 使用案例

    假设有布局文件item_student.xml布局文件, 其中只有一个TextView用来显示学生姓名

    <?xml version="1.0" encoding="utf-8"?>
    <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="wrap_content"
        >
    
        <TextView
            android:id="@+id/tv_student_name"
            style="@style/text_2.body.dark"
            android:layout_width="0dp"
            android:layout_marginStart="20dp"
            android:layout_marginEnd="20dp"
            android:padding="10dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:text="学生姓名"
            />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    假设有学生实体类Student.kt

    class Student {
        var name: String = ""
    }
    

    重点: 根据Binding类和实体类创建Adapter

    class StudentAdapter : CommonRvAdapter<Student, ItemStudentBinding>() {
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CommonRvHolder<ItemStudentBinding> {
            // 使用Binding类解析布局设置到Holder上
            val inflate = ItemStudentBinding.inflate(LayoutInflater.from(parent.context), parent, false)
            return CommonRvHolder(inflate)
        }
        
        override fun onBindViewHolder(holder: CommonRvHolder<ItemStudentBinding>, position: Int, binding: ItemStudentBinding, bean: Student) {
            // binding对象中包含有所有的控件, bean对象包含有所有的实体属性
            binding.tvStudentName.text = bean.name
            binding.root.setOnClickListener {
                ToastUtils.showShort("你点击了${bean.name}同学")
            }
        }
    }
    

    填充数据

    val students = mutableListOf<Student>()
    for (i in 0 until 100) {
        students.add(Student().apply { name = "同学$i" })
    }
    adapter.data = students
    

    相关文章

      网友评论

        本文标题:安卓ViewBinding与RecyclerView Adapt

        本文链接:https://www.haomeiwen.com/subject/qfdcfltx.html