文章目录

  • 一、@BindingAdapter 注解
    • 1、注解简介
    • 2、使用 @BindingAdapter 注解为布局组件绑定自定义逻辑
  • 二、使用 @BindingAdapter 注解绑定加载网络图片静态方法
  • 三、使用 @BindingAdapter 注解绑定加载本地图片静态方法
  • 四、使用 @BindingAdapter 注解绑定加载网络图片或本地图片静态方法
  • 五、完整代码示例
    • 1、build.gradle 构建脚本
    • 2、AndroidManifest.xml 清单文件
    • 3、DataBinding 布局文件
    • 4、BindingAdapter 注解类
    • 5、MainActivity 组件
    • 6、执行结果

博客源码 : https://download.csdn.net/download/han1202012/87701531

一、@BindingAdapter 注解


BindingAdapter DataBinding 数据绑定技术 的组成部分 ;

1、注解简介

借助 @BindingAdapter 注解 可以 将自定义逻辑 绑定到 DataBinding 布局中 ;

在 DataBinding 布局中 , 不只是机械性的显示内容 或者 拼接内容 , 还需要 进行更复杂的操作 ;

如 : 为 ImageView 组件绑定数据模型 , 传入一个 url 网络图片地址 , 在该组件中显示网络图片 , 如果网络图片加载失败或者为空 , 则加载默认的本地资源 ;

上述操作必须 自定义一段代码逻辑进行实现 , 使用简单的数据绑定无法实现该功能 ;

2、使用 @BindingAdapter 注解为布局组件绑定自定义逻辑

首先 , 启用 DataBinding , 在 DataBinding 数据绑定 布局中 引入 绑定的数据模型 ;

<data><variablename="变量名"type="变量类型" /></data>

然后 , 在 DataBinding 布局中 , 为组件的 app:注解参数 属性设置 "@{变量名}" 属性值 ; 该属性名称 注解参数 就是使用 @BindingAdapter("注解参数") 注解修饰的 Java 静态函数 ;

<ImageViewandroid:id="@+id/imageView"android:layout_width="100dp"android:layout_height="100dp"app:注解参数="@{变量名}"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintVertical_bias="0.2"/>

最后 , 定义 BindingAdapter 静态方法 , 该静态方法使用 @BindingAdapter 注解修饰 , 方法的参数就是 @{变量名} 类型的参数 ;

  • 该方法中第一个参数是 布局中的组件
  • 第二个参数是 DataBinding 布局中 绑定的 数据模型
@JvmStatic@BindingAdapter("注解参数")fun setImage(组件参数名称: 组件类型, 绑定变量名: 变量类型) {// 绑定的代码逻辑}

注解参数 DataBinding 布局中的组件 app:注解参数 属性名称 对应 ;

DataBinding 布局中的 变量名 组件 app:注解参数 属性值 对应 ;

二、使用 @BindingAdapter 注解绑定加载网络图片静态方法


在 DataBinding 布局中 , 绑定数据模型 ;

<data><variablename="imageNetwork"type="String" /></data>

在 ImageView 组件中 , 设置 app:image="@{imageNetwork}" 属性 , imageNetwork 是绑定的数据 ;

app:image 属性 , 对应着 @BindingAdapter("image") 注解中的 注解参数 image ;

<ImageViewandroid:id="@+id/imageView"android:layout_width="100dp"android:layout_height="100dp"app:image="@{imageNetwork}"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintVertical_bias="0.2"/>

在 Kotlin 中 , 定义 Java 静态方法 , 需要在 companion object 伴生对象 中 , 使用 @JvmStatic 修饰函数 ;

使用 @BindingAdapter("image") 修饰函数 , 其中的注解参数 image 对应组件中的 app:image 属性 ;

imageView: ImageView 参数是 DataBinding 布局中的 被绑定的组件 ;

url: String 参数是 DataBinding 布局中绑定的数据模型 ;

class ImageViewBindingAdapter {companion object {/*DataBinding 布局中 ImageView 适配器 - imageView: ImageView 参数就是布局中的 ImageView - url: String 参数是 ImageView 的 app:image 属性值 - app:image="@{imageNetwork}" - imageUrl 该值是  标签中的 variable , 类型为 String */@JvmStatic@BindingAdapter("image")fun setImage(imageView: ImageView, url: String) {// 加载网络图片if (!TextUtils.isEmpty(url)) {Picasso.get().load(url).into(imageView);} else {imageView.setBackgroundColor(Color.GREEN)}}}}

在 Activity 组件中 , 向 DataBinding 布局中设置 imageNetwork 数据模型的对象 ;

// 设置布局文件// 布局文件是 activity_main.xml// 该类名称生成规则是 布局文件名称 + Bindingvar activityMainBinding: ActivityMainBinding =DataBindingUtil.setContentView(this, R.layout.activity_main)// 为布局 设置 数据activityMainBinding.imageNetwork = "https://img-blog.csdnimg.cn/0d611b315e8448f7a01f7a772c238c6f.png"

三、使用 @BindingAdapter 注解绑定加载本地图片静态方法


在 DataBinding 布局中 , 绑定数据模型 ;

<data><variablename="imageLocal"type="int" /></data>

在 ImageView 组件中 , 设置 app:image="@{imageLocal}" 属性 , imageLocal 是绑定的数据 ;

app:image 属性 , 对应着 @BindingAdapter("image") 注解中的 注解参数 image ;

<ImageViewandroid:id="@+id/imageView2"android:layout_width="100dp"android:layout_height="100dp"app:image="@{imageLocal}"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintVertical_bias="0.4"/>

在 Kotlin 中 , 定义 Java 静态方法 , 需要在 companion object 伴生对象 中 , 使用 @JvmStatic 修饰函数 ;

使用 @BindingAdapter("image") 修饰函数 , 其中的注解参数 image 对应组件中的 app:image 属性 ;

imageView: ImageView 参数是 DataBinding 布局中的 被绑定的组件 ;

resourceId: Int 参数是 DataBinding 布局中绑定的数据模型 ;

class ImageViewBindingAdapter {companion object {/*DataBinding 布局中 ImageView 适配器 - imageView: ImageView 参数就是布局中的 ImageView - resourceId: Int 参数是 ImageView 的 app:image 属性值 - app:image="@{imageLocal}" - imageLocal 该值是  标签中的 variable , 类型为 int */@JvmStatic@BindingAdapter("image")fun setImage(imageView: ImageView, resourceId: Int) {imageView.setImageResource(resourceId)}}}

在 Activity 组件中 , 向 DataBinding 布局中设置 imageNetwork 数据模型的对象 ;

// 设置布局文件// 布局文件是 activity_main.xml// 该类名称生成规则是 布局文件名称 + Bindingvar activityMainBinding: ActivityMainBinding =DataBindingUtil.setContentView(this, R.layout.activity_main)// 为布局 设置 数据activityMainBinding.imageLocal = R.mipmap.ic_launcher

四、使用 @BindingAdapter 注解绑定加载网络图片或本地图片静态方法


在 DataBinding 布局中 , 绑定数据模型 ;

<data><variablename="imageNetwork"type="String" /><variablename="imageLocal"type="int" /></data>

在 ImageView 组件中 ,

设置 app:image="@{imageNetwork}" 属性 , imageNetwork 是绑定的数据 ;

设置 app:imageDefaultRes="@{imageLocal}"" 属性 , imageLocal 是绑定的数据 ;

app:image 属性 , 对应着 @BindingAdapter("image") 注解中的 注解参数 image ;

<ImageViewandroid:id="@+id/imageView3"android:layout_width="100dp"android:layout_height="100dp"app:image="@{imageNetwork}"app:imageDefaultRes="@{imageLocal}"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintVertical_bias="0.6"/>

在 Kotlin 中 , 定义 Java 静态方法 , 需要在 companion object 伴生对象 中 , 使用 @JvmStatic 修饰函数 ;

使用 @BindingAdapter(value = ["image", "imageDefaultRes"], requireAll = false) 修饰函数 ,

  • 其中的注解参数 value = ["image", "imageDefaultRes"] 对应组件中的 app:imageapp:imageDefaultRes"属性 ;
  • requireAll = false 表示这两个注解属性 , 不是必须都齐全的 , 可以设置任意一个 , 也可以都设置 ;

imageView: ImageView 参数是 DataBinding 布局中的 被绑定的组件 ;

url: String 参数是 DataBinding 布局中绑定的数据模型 ;

<variablename="imageNetwork"type="String" />

resourceId: Int 参数是 DataBinding 布局中绑定的数据模型 ;

<variablename="imageLocal"type="int" />
class ImageViewBindingAdapter {companion object {/*DataBinding 布局中 ImageView 适配器 - imageView: ImageView 参数就是布局中的 ImageView - url: String 参数是 ImageView 的 app:image 属性值 - app:image="@{imageNetwork}" - imageUrl 该值是  标签中的 variable , 类型为 String - resourceId: Int 参数是 ImageView 的 app:image 属性值 - app:image="@{imageLocal}" - imageLocal 该值是  标签中的 variable , 类型为 int注意 : 如果是 Java 静态函数 , 注解为@BindingAdapter(value = ["image", "imageDefaultRes"], requireAll = false)Kotlin 中使用 [] 初始化数组 , Java 中使用 {} 初始化数组 */@JvmStatic@BindingAdapter(value = ["image", "imageDefaultRes"], requireAll = false)fun setImage(imageView: ImageView, url: String, resourceId: Int) {// 加载网络图片if (!TextUtils.isEmpty(url)) {Picasso.get().load(url).into(imageView);} else {imageView.setImageResource(resourceId)}}}}

在 Activity 组件中 , 向 DataBinding 布局中设置 imageNetwork 数据模型的对象 ;

// 设置布局文件// 布局文件是 activity_main.xml// 该类名称生成规则是 布局文件名称 + Bindingvar activityMainBinding: ActivityMainBinding =DataBindingUtil.setContentView(this, R.layout.activity_main)// 为布局 设置 数据activityMainBinding.imageLocal = R.mipmap.ic_launcher

五、完整代码示例


1、build.gradle 构建脚本

plugins {id 'com.android.application'id 'org.jetbrains.kotlin.android'id 'kotlin-kapt'}android {namespace 'kim.hsl.databinding_demo'compileSdk 32defaultConfig {applicationId "kim.hsl.databinding_demo"minSdk 21targetSdk 32versionCode 1versionName "1.0"testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"// 启用 DataBindingdataBinding {enabled = true}}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility 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、AndroidManifest.xml 清单文件

<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><uses-permission android:name="android.permission.INTERNET" /><applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.DataBinding_Demo"tools:targetApi="31"><activityandroid:name=".MainActivity"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter><meta-dataandroid:name="android.app.lib_name"android:value="" /></activity></application></manifest>

3、DataBinding 布局文件

<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><variablename="imageNetwork"type="String" /><variablename="imageLocal"type="int" /></data><androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><ImageViewandroid:id="@+id/imageView"android:layout_width="100dp"android:layout_height="100dp"app:image="@{imageNetwork}"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintVertical_bias="0.2"/><ImageViewandroid:id="@+id/imageView2"android:layout_width="100dp"android:layout_height="100dp"app:image="@{imageLocal}"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintVertical_bias="0.4"/><ImageViewandroid:id="@+id/imageView3"android:layout_width="100dp"android:layout_height="100dp"app:image="@{imageNetwork}"app:imageDefaultRes="@{imageLocal}"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintVertical_bias="0.6"/></androidx.constraintlayout.widget.ConstraintLayout></layout>

4、BindingAdapter 注解类

package kim.hsl.databinding_demoimport android.graphics.Colorimport android.text.TextUtilsimport android.widget.ImageViewimport androidx.databinding.BindingAdapterimport com.squareup.picasso.Picassoclass ImageViewBindingAdapter {companion object{/*DataBinding 布局中 ImageView 适配器 - imageView: ImageView 参数就是布局中的 ImageView - url: String 参数是 ImageView 的 app:image 属性值 - app:image="@{imageNetwork}" - imageUrl 该值是  标签中的 variable , 类型为 String */@JvmStatic@BindingAdapter("image")fun setImage(imageView: ImageView, url: String) {// 加载网络图片if (!TextUtils.isEmpty(url)) {Picasso.get().load(url).into(imageView);} else {imageView.setBackgroundColor(Color.GREEN)}}/*DataBinding 布局中 ImageView 适配器 - imageView: ImageView 参数就是布局中的 ImageView - resourceId: Int 参数是 ImageView 的 app:image 属性值 - app:image="@{imageLocal}" - imageLocal 该值是  标签中的 variable , 类型为 int */@JvmStatic@BindingAdapter("image")fun setImage(imageView: ImageView, resourceId: Int) {imageView.setImageResource(resourceId)}/*DataBinding 布局中 ImageView 适配器 - imageView: ImageView 参数就是布局中的 ImageView - url: String 参数是 ImageView 的 app:image 属性值 - app:image="@{imageNetwork}" - imageUrl 该值是  标签中的 variable , 类型为 String - resourceId: Int 参数是 ImageView 的 app:image 属性值 - app:image="@{imageLocal}" - imageLocal 该值是  标签中的 variable , 类型为 int注意 : 如果是 Java 静态函数 , 注解为@BindingAdapter(value = ["image", "imageDefaultRes"], requireAll = false)Kotlin 中使用 [] 初始化数组 , Java 中使用 {} 初始化数组 */@JvmStatic@BindingAdapter(value = ["image", "imageDefaultRes"], requireAll = false)fun setImage(imageView: ImageView, url: String, resourceId: Int) {// 加载网络图片if (!TextUtils.isEmpty(url)) {Picasso.get().load(url).into(imageView);} else {imageView.setImageResource(resourceId)}}}}

5、MainActivity 组件

package kim.hsl.databinding_demoimport androidx.appcompat.app.AppCompatActivityimport android.os.Bundleimport androidx.databinding.DataBindingUtilimport kim.hsl.databinding_demo.databinding.ActivityMainBindingclass MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// 设置布局文件// 布局文件是 activity_main.xml// 该类名称生成规则是 布局文件名称 + Bindingvar activityMainBinding: ActivityMainBinding =DataBindingUtil.setContentView(this, R.layout.activity_main)// 为布局 设置 数据activityMainBinding.imageNetwork = "https://img-blog.csdnimg.cn/0d611b315e8448f7a01f7a772c238c6f.png"activityMainBinding.imageLocal = R.mipmap.ic_launcher}}

6、执行结果


本篇博客加载的图片 :

博客源码 : https://download.csdn.net/download/han1202012/87701531