【Jetpack】DataBinding 架构组件 ⑥ ( RecyclerView 数据绑定 )

news2024/9/20 18:35:03

文章目录

  • 一、RecyclerView 数据绑定核心要点
    • 1、启用数据绑定 / 导入依赖
    • 2、RecyclerView 条目 DataBinding 布局
    • 3、自定义 RecyclerView.Adapter 适配器要点 ( 本博客重点 ★ )
  • 二、RecyclerView 数据绑定源码示例
    • 1、build.gradle 构建脚本 ( 启用数据绑定 / 导入依赖 )
    • 2、主界面的 Activity 布局与组件 ( 可不使用 DataBinding )
      • 布局文件
      • Activity 组件的 Kotlin 代码
    • 3、自定义 RecyclerView.Adapter
      • 数据类
      • DataBinding 布局
      • RecyclerView.Adapter
    • 4、执行结果





一、RecyclerView 数据绑定核心要点




1、启用数据绑定 / 导入依赖


在 RecyclerView 中 , 如果要使用 DataBinding 架构组件进行数据绑定 , 首先要 启用 DataBinding , 并 导入 RecyclerView 依赖 , 在 Module 模块下的 build.gradle 构建脚本 中 , 配置如下内容 :

android {
	// 启用 DataBinding 数据绑定
    dataBinding {
        enabled = true
    }
}

dependencies {
	// 导入 RecyclerView 依赖
    implementation 'androidx.recyclerview:recyclerview:1.2.1'
}

2、RecyclerView 条目 DataBinding 布局


要绑定的数据是 RecyclerView 条目的数据 , 因此需要 将条目布局设置为 DataBinding 布局 ;

创建 item.xml 布局后 , 将光标放置在第一个字符位置 , 按下 Alt + 回车 , 弹出如下下拉菜单 ,

在这里插入图片描述

选择 " Convert to data binding layout " 选项 , 可以将正常的 约束布局 的 布局文件 , 转为 DataBinding 布局文件 ;

转换完毕后 , 该 item.xml 布局 生成对应的 ItemBinding 类 , 将数据绑定在该布局类中即可 ;


3、自定义 RecyclerView.Adapter 适配器要点 ( 本博客重点 ★ )


自定义 RecyclerView.Adapter 适配器 中 , 需要 实现对 RecyclerView 条目 DataBinding 布局 的 数据绑定 ;

首先 , 自定义 RecyclerView.ViewHolder 类 , 在其中维护 item.xml 布局文件 对应的 ItemBinding 数据绑定类实例对象 , 在构造函数中设置改 ItemBinding 对象 ;

    class MyViewHolder: RecyclerView.ViewHolder {
        /**
         * RecyclerView 列表项布局文件是 item.xml
         * 生成的对应的 DataBinding 类是 ItemBinding 类
         * ItemBinding 类等同于布局文件
         */
        lateinit var itemBinding: ItemBinding
        constructor(itemView: View) : super(itemView)
        constructor(itemBinding: ItemBinding) : super(itemBinding.root){
            this.itemBinding = itemBinding
        }
    }

然后 ,自定义 RecyclerView.Adapter 类中重写的 onCreateViewHolder 函数中 , 获取 DataBinding 布局 , 并将其设置给 自定义的 RecyclerView.ViewHolder 对象 ;

  • 获取 DataBinding 布局 : 调用 DataBindingUtil.inflate 函数 , 获取 item.xml 对应的 DataBinding 布局文件类 ItemBinding 实例对象 ;
  • 将 DataBinding 布局设置给自定义 RecyclerView.ViewHolder 实例 : 将上面创建的 ItemBinding 对象通过 构造函数设置到 MyViewHolder 中 ;
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        // 获取 DataBinding 布局
        var itemBinding: ItemBinding = DataBindingUtil.inflate<ItemBinding>(
            LayoutInflater.from(parent.context),
            R.layout.item,
            parent,
            false)
        // 将 DataBinding 布局设置给 ViewHolder
        return MyViewHolder(itemBinding)
    }

最后 ,自定义 RecyclerView.Adapter 类中重写的 onBindViewHolder 函数中 , 为每个列表条目设置数据 ;

  • 先通过参数中的 MyViewHolder 对象获取其中的 ItemBinding 数据绑定布局对象 ;
  • 之后为 holder.itemBinding 设置 Student 数据类对象 ;
    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        holder.itemBinding.student = list[position]
    }




二、RecyclerView 数据绑定源码示例




1、build.gradle 构建脚本 ( 启用数据绑定 / 导入依赖 )


Module 模块下的 build.gradle 构建脚本 中 , 主要是 启用 DataBinding ;

RecyclerView 不需要单独导入依赖 , 在 引入的 'androidx.appcompat:appcompat:1.4.1' 依赖中 , 就包含了 RecyclerView 依赖 ;


build.gradle 构建脚本 :

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
    id 'kotlin-kapt'
}

android {
    namespace 'kim.hsl.databinding_demo'
    compileSdk 32

    defaultConfig {
        applicationId "kim.hsl.databinding_demo"
        minSdk 21
        targetSdk 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

        // 启用 DataBinding
        dataBinding {
            enabled = true
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '9'
    }
}

dependencies {
    implementation 'androidx.core:core-ktx:1.7.0'
    implementation 'androidx.appcompat:appcompat:1.4.1'
    implementation 'com.google.android.material:material:1.5.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

    implementation 'com.squareup.picasso:picasso:2.71828'
}

2、主界面的 Activity 布局与组件 ( 可不使用 DataBinding )


Activity 组件的布局 可以使用 数据绑定 , 也可以不使用 , 该布局中没有绑定数据 ;

  • 使用了 DataBinding 布局 : 在布局中使用 DataBinding 样式的布局 , 根标签是 layout 标签 , 其中有 data 子标签 , 其中没有维护任何数据 ; 在 Activity 中使用 DataBindingUtil.setContentView 设置布局文件 ;
  • 不使用 DataBinding 布局 : 直接使用普通布局 , 在 Activity 中使用 findViewById 获取并设置 RecyclerView 组件 ;

布局文件

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

Activity 组件的 Kotlin 代码

package kim.hsl.databinding_demo

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.LinearLayoutManager
import kim.hsl.databinding_demo.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // 设置布局文件
        // 布局文件是 activity_main.xml
        // 该类名称生成规则是 布局文件名称 + Binding
        var activityMainBinding: ActivityMainBinding =
            DataBindingUtil.setContentView(this, R.layout.activity_main)

        // 设置 RecyclerView 的 布局管理器 / 数据适配器
        activityMainBinding.recyclerView.layoutManager = LinearLayoutManager(this)
        var adapter = StudentAdapter()
        activityMainBinding.recyclerView.adapter = adapter
    }
}

3、自定义 RecyclerView.Adapter


DataBinding 布局 RecyclerView 中条目的布局 , 需要 在 自定义 RecyclerView.Adapter 中 , 为每个条目布局都绑定一个 Student 数据类 ;

在 DataBinding 布局中 , 绑定了 kim.hsl.databinding_demo.Student 类型的数据 , 在 TextView 中显示该绑定数据类对象的 name 和 age 字段 ;

    <data>
        <variable
            name="student"
            type="kim.hsl.databinding_demo.Student" />
    </data>

数据绑定布局 ItemBinding , 在 class MyViewHolder: RecyclerView.ViewHolder 类中维护 , 可以通过该类获取数据绑定布局 , 并为其设置数据 ;

RecyclerView.Adapter#onCreateViewHolder 中 , 调用 DataBindingUtil.inflate 函数加载布局 , 并设通过构造函数设置给 MyViewHolder ;


数据类

package kim.hsl.databinding_demo

class Student(var name: String, var age: Int) {
}

DataBinding 布局

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>
        <variable
            name="student"
            type="kim.hsl.databinding_demo.Student" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="50dip">

        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{student.name}"
            android:textSize="24sp"
            tools:text="Tom"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.3"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/age"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{String.valueOf(student.age)}"
            android:textSize="24sp"
            tools:text="18"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.7"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

RecyclerView.Adapter

package kim.hsl.databinding_demo

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import kim.hsl.databinding_demo.databinding.ItemBinding

class StudentAdapter: RecyclerView.Adapter<StudentAdapter.MyViewHolder>() {

    var list = listOf(
        Student("Tom", 18),
        Student("Jerry", 12),
        Student("Mickey", 16),
        Student("Donald", 14)
    )

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        // 获取 DataBinding 布局
        var itemBinding: ItemBinding = DataBindingUtil.inflate<ItemBinding>(
            LayoutInflater.from(parent.context),
            R.layout.item,
            parent,
            false)
        // 将 DataBinding 布局设置给 ViewHolder
        return MyViewHolder(itemBinding)
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        holder.itemBinding.student = list[position]
    }

    override fun getItemCount(): Int {
        return list.size
    }

    class MyViewHolder: RecyclerView.ViewHolder {
        /**
         * RecyclerView 列表项布局文件是 item.xml
         * 生成的对应的 DataBinding 类是 ItemBinding 类
         * ItemBinding 类等同于布局文件
         */
        lateinit var itemBinding: ItemBinding
        constructor(itemView: View) : super(itemView)
        constructor(itemBinding: ItemBinding) : super(itemBinding.root){
            this.itemBinding = itemBinding
        }
    }
}

4、执行结果


在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/448871.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ggplot中的注释图层annotate

文章目录 介绍利用注释层添加图形利用注释层添加文本利用注释层添加公式 介绍 ggplot作图包中除了常见的geom图层外&#xff0c;还有一个annotate的注释图层&#xff0c;实现对作图对象的额外添加&#xff0c;其添加要素不在ggplot()所接受的数据框中。 利用注释层添加图形 …

家政服务APP小程序开发功能详解

随着人们生活水平的提高&#xff0c;对家政服务的要求也越来越高。而传统的到家政公司寻找服务人员的方法显然已经无法满足人们需求&#xff0c;取而代之的是线上预约家政服务。家政服务App小程序软件可以满足用户在线预约&#xff0c;还可以根据自己的需求定制家政服务、选择家…

【Hadoop-CosDistcp】通过CosDistcp的方式迁移Cos中的数据至HDFS

【Hadoop-CosDistcp】通过CosDistcp的方式迁移Cos中的数据至HDFS 1&#xff09;功能说明2&#xff09;使用环境3&#xff09;下载与安装4&#xff09;原理说明5&#xff09;参数说明6&#xff09;使用示例7&#xff09;迁移 Cos 中的数据至 HDFS 及数据校验7.1.数据迁移7.2.数据…

【Unity入门】16.脚本引用组件

【Unity入门】脚本引用组件 大家好&#xff0c;我是Lampard~~ 欢迎来到Unity入门系列博客&#xff0c;所学知识来自B站阿发老师~感谢 &#xff08;一&#xff09;脚本引用普通组件 &#xff08;1&#xff09;点击控制音频播放 还记得我们的车载音乐AudioSource吗&#xff1f;…

zabbix搭建

1.环境 本实验使用一台centos7主机&#xff0c;关闭了firewalld和selinux服务&#xff0c;zabbix版本为5.0版本&#xff0c;mysql使用版本为5.7版本 若要搭建6.0以上版本的zabbix&#xff0c;则需要使用mysql 8.0以上的版本 其它版本的zabbix可参考zabbix官网:Download and…

YOLOv5+单目实现三维跟踪(python)

YOLOv5单目跟踪&#xff08;python&#xff09; 1. 目标跟踪2. 测距模块2.1 设置测距模块2.2 添加测距 3. 主代码4. 实验效果 相关链接 1. YOLOv5单目测距&#xff08;python&#xff09; 2. YOLOv7单目测距&#xff08;python&#xff09; 3. YOLOv7单目跟踪&#xff08;pytho…

C++练级之初级:第四篇

C练级之初级&#xff1a;第四篇 引用 C练级之初级&#xff1a;第四篇1.引用1.1引用的介绍1.2引用的使用场景1.3常引用 2.引用的底层3.引用的与指针的比较 总结 1.引用 1.1引用的介绍 &#x1f914;首先还是一个问题&#xff0c;引用是解决C语言什么不足&#xff1f; 指针在&am…

Python自动化sql注入:布尔盲注

在sql注入时&#xff0c;使用python脚本可以大大提高注入效率&#xff0c;这里演示一下编写python脚本实现布尔盲注的基本流程&#xff1a; 演示靶场&#xff1a;sqli-labs 布尔盲注 特点&#xff1a;没有回显没有报错&#xff0c;但根据sql语句正常与否返回不同结果&#x…

新手做电商直播带货怎么和快递合作谈价格

新手做电商直播带货怎么和快递合作谈价格达人带货一般怎样的合作模式&#xff1f;#达人带货 #直播带货 #红人 #百收网 跟快递谈价其实是有方法的&#xff0c;快递的价格不是说不能打下来&#xff0c;就是需要你们多一点点的心机。这个视频我就再给你们补充三个方法&#xff0c;…

HCIP之STP

企业网三层架构 线路冗余—二层网络桥接环路 因为路由器的路由表是由相对完善的计算所得&#xff0c;且存在防环规则&#xff1b;故路由器物理链路上实施备份时&#xff0c;一般不会出现环路&#xff1b;但交换转发数据依赖MAC表&#xff08;CAM表&#xff09;&#xff0c;该表…

【模式识别4】YOLO目标检测数据集xml格式转txt格式

YOLO目标检测数据集xml格式转txt格式 1. 转换前的xml格式2. xml格式转txt格式代码2.1 源代码2.2 需要修改的地方 3. 转换后的txt格式 代码资源&#xff1a;voc2txt.py 1. 转换前的xml格式 如果我们使用LabelImg工具标注数据集&#xff0c;生成的xml文件如下&#xff1a; xml…

Linux运维:推荐八款Linux远程连接工具

目录 2、XShell 3、SecureCRT 4、PuTTY 5、WindTerm 6、iTerm2 7、MobaXterm 8、Termius 今天给大家推荐八款Linux远程连接工具&#xff0c;非常实用&#xff0c;希望对大家能有所帮助&#xff01; 1、NxShell NxShell是一款开源的Linux远程管理工具&#xff0c;是我日…

Spring Boot 接口加解密

1. 介绍 在我们日常的Java开发中&#xff0c;免不了和其他系统的业务交互&#xff0c;或者微服务之间的接口调用 如果我们想保证数据传输的安全&#xff0c;对接口出参加密&#xff0c;入参解密。 但是不想写重复代码&#xff0c;我们可以提供一个通用starter&#xff0c;提…

【python数据可视化】基于networkx的10个绘图技巧

一、说明 networkx在02年5月产生&#xff0c;是用python语言编写的软件包&#xff0c;便于用户对复杂网络进行创建、操作和学习。利用networkx可以以标准化和非标准化的数据格式存储网络、生成多种随机网络和经典网络、分析网络结构、建立网络模型、设计新的网络算法、进行网络…

解决java.lang.IllegalStateException: Failed to load ApplicationContext错误~

错误描述&#xff1a; Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: file [D:\SSM\SSM_3.22\spring_transaction\target\classes\spring_txAnnotation\Controller\BookController.class]; nested …

装饰器模式C++用法示例

六.装饰器模式 一.装饰器模式1.原理2.适用场景 二.C程序示例1.语法组成2.C示例 一.装饰器模式 1.原理 装饰器模式是一种结构性设计模式&#xff0c;其目的是通过包装对象来扩展其行为而不改变其接口。该模式可以动态地将责任附加到对象上&#xff0c;从而提供一种灵活的替代方…

SQL Server基础 第三章 数据表基本操作(增删改查,不允许保存更改异常!)

往表里插数据我们现在有两种方式第一种是编辑直接修改&#xff0c;第二种是通过查询来修改数据 两种方法的区别 第一种更直接&#xff0c;如果数据量小那么直接改就好了&#xff0c;那如果数据量稍微庞大我们就需要用新建查询来进行表内容的修改了&#xff01;&#xff01;&a…

【Linux】进程信号 --- 信号的产生 保存 捕捉递达

被爱情困住的是傻子 文章目录 一、信号的预备知识1.通过生活例子来理解信号2.迁移到进程上来理解信号 二、信号的发送&#xff08;修改PCB的信号位图&#xff09;1.通过键盘发送信号&#xff08;kill指令 和 热键&#xff09;2.通过系统调用发送信号&#xff08;kill系统调用 和…

前端技术的miniui 和bootstartp

前端技术的miniui 和bootstartp 目录概述需求&#xff1a; 设计思路实现思路分析1.前端技术boostatrp2.miniui: 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better re…

1686_MATLAB处理Excel文件

全部学习汇总&#xff1a; GreyZhang/g_matlab: MATLAB once used to be my daily tool. After many years when I go back and read my old learning notes I felt maybe I still need it in the future. So, start this repo to keep some of my old learning notes servral …