当前位置:网站首页>Jetpack's dataBinding
Jetpack's dataBinding
2022-08-11 06:34:00 【The rest of my life love static】
一、概览
数据绑定库(dataBinding)是一种支持库,借助该库,您可以使用Declarative format(而非程序化地)将布局中的界面组件绑定到应用中的数据源.
二、使用入门
要将应用配置为使用数据绑定,请在应用模块的 build.gradle 文件中添加 dataBinding 元素
dataBinding {
enabled = true
}
三、布局和绑定表达式
数据绑定布局文件略有不同,以根标记 layout开头,后跟 data 元素和 view 根元素.此视图元素是非绑定布局文件中的根.
User
data class User(val firstName: String, val lastName: String) {
var like: Int = 0
}
activity_normal
<?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="user"
type="com.anniljing.jetpackviewmodel.model.User" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.NormalActivity">
<TextView
android:id="@+id/normalName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<TextView
android:id="@+id/normalLike"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="@id/normalName"
app:layout_constraintTop_toTopOf="@id/normalName"
android:text="@{Integer.toString(user.like)}"
android:layout_marginLeft="20dp"/>
<Button
android:id="@+id/addLikeBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="@id/normalName"
app:layout_constraintTop_toBottomOf="@id/normalName"
android:text="Like"
android:onClick="addLike"/>
<TextView
android:id="@+id/currentLike"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="@id/addLikeBtn"
app:layout_constraintTop_toBottomOf="@id/addLikeBtn"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
data标签
dataThere are two types of sub-tabs below the tab:import和variable,variable 标签为变量,Similar to how we defined a variable,name 为变量名,type Fully qualified type name for the variable,包括包名.布局中通过 @{} to refer to the value of this variable,{} can be any Java 表达式;
<variable
name="user"
type="com.anniljing.jetpackviewmodel.model.User" />
同样,我们还可以使用import来定义变量
<import
alias="User"
type="com.anniljing.jetpackviewmodel.model.User" />
<variable
name="user"
type="User" />
NormalActivity
class NormalActivity : AppCompatActivity() {
private var binding:ActivityNormalBinding ?=null
private val user=User("张三","李四")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding=DataBindingUtil.setContentView(this,R.layout.activity_normal)
user.like=1
binding!!.user=user
}
fun addLike(view: View) {
user.like=user.like+1
binding!!.currentLike.text="Current likes:"+user.like
}
}

上面截图可以看出,No matter how you increase the number of likes,will not be timely“更新”到UI上,Is there any solution to achieve dynamic updateUI呢?答案是肯定的,使用可观察的数据对象.
使用可观察的数据对象
可观察性是指一个对象将其数据变化告知其他对象的能力.通过数据绑定库,您可以让对象、字段或集合变为可观察.当其中一个可观察数据对象绑定到界面并且该数据对象的属性发生更改时,界面会自动更新.
可观察字段
在创建实现 Observable 接口的类时要完成一些操作,但如果您的类只有少数几个属性,这样操作的意义不大.在这种情况下,您可以使用通用 Observable 类和以下特定于基元的类,将字段设为可观察字段:
- ObservableBoolean
- ObservableBoolean
- ObservableByte
- ObservableChar
- ObservableShort
- ObservableInt
- ObservableLong
- ObservableFloat
- ObservableDouble
- ObservableParcelable
ObservableUser
package com.anniljing.jetpackviewmodel.model
import androidx.databinding.ObservableInt
data class ObservableUser(val firstName:String, val like:ObservableInt)
activity_observable_normal
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="user"
type="com.anniljing.jetpackviewmodel.model.ObservableUser" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/normalLike"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:text="@{Integer.toString(user.like)}"/>
<Button
android:id="@+id/addLikeBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="addLike"
android:text="Like" />
<TextView
android:id="@+id/currentLike"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</layout>
ObservableNormalActivity
package com.anniljing.jetpackviewmodel.activity
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.databinding.ObservableInt
import com.anniljing.jetpackviewmodel.R
import com.anniljing.jetpackviewmodel.databinding.ActivityObservableNormalBinding
import com.anniljing.jetpackviewmodel.model.ObservableUser
class ObservableNormalActivity : AppCompatActivity() {
private lateinit var binding: ActivityObservableNormalBinding
private val observableUser = ObservableUser("张三", ObservableInt(0))
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding =
DataBindingUtil.setContentView(this, R.layout.activity_observable_normal)
binding.user = observableUser
}
fun addLike(view: View) {
observableUser.like.set(observableUser.like.get() + 1)
binding!!.currentLike.text = "Current likes:" + observableUser.like.get()
}
}

可观察对象
实现 Observable 接口The class allows to register listeners,以便它们接收有关可观察对象的属性更改的通知.Observable 接口具有添加和移除监听器的机制,但何时发送通知必须由您决定.为便于开发,数据绑定库提供了用于实现监听器注册机制的 BaseObservable 类.实现 BaseObservable 的数据类负责在属性更改时发出通知.具体操作过程是向 getter 分配 Bindable 注释,然后在 setter 中调用 notifyPropertyChanged() 方法
CustomObservableUser
package com.anniljing.jetpackviewmodel.model
import androidx.databinding.BaseObservable
import androidx.databinding.Bindable
import androidx.databinding.library.baseAdapters.BR
class CustomObservableUser : BaseObservable() {
@get:Bindable
var firstName: String = ""
set(value) {
field = value
notifyPropertyChanged(BR.firstName)
}
@get:Bindable
var like: Int = 0
set(value) {
field = value
notifyPropertyChanged(BR.like)
}
}
PS:
1、要导入androidx.databinding.library.baseAdapters.BR
2、如果在notifyPropertyChangedcannot be included in the parametersBRwhen pointing to an attribute,可以执行android studio工具栏build---->make progect
activity_observable_custom
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="user"
type="com.anniljing.jetpackviewmodel.model.CustomObservableUser" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<TextView
android:id="@+id/normalLike"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:text="@{Integer.toString(user.like)}"/>
<Button
android:id="@+id/addLikeBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="addLike"
android:text="Like" />
<TextView
android:id="@+id/currentLike"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</layout>
ObservableCustomActivity
package com.anniljing.jetpackviewmodel.activity
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.databinding.ObservableInt
import com.anniljing.jetpackviewmodel.R
import com.anniljing.jetpackviewmodel.databinding.ActivityObservableCustomBinding
import com.anniljing.jetpackviewmodel.databinding.ActivityObservableNormalBinding
import com.anniljing.jetpackviewmodel.model.CustomObservableUser
import com.anniljing.jetpackviewmodel.model.ObservableUser
class ObservableCustomActivity : AppCompatActivity() {
private lateinit var binding: ActivityObservableCustomBinding
private val observableUser = CustomObservableUser()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding =
DataBindingUtil.setContentView(this, R.layout.activity_observable_custom)
binding.user = observableUser
}
fun addLike(view: View) {
observableUser.like=observableUser.like+ 1
binding!!.currentLike.text = "Current likes:" + observableUser.like
}
}

四、绑定适配器
The binding adapter is responsible for issuing the corresponding framework calls设置值.例如,设置属性值就像调用 setText() 方法一样.再比如,设置事件监听器就像调用 setOnClickListener() 方法.
数据绑定库允许您通过使用适配器指定为设置值而调用的方法、提供您自己的绑定逻辑,以及指定返回对象的类型.
指定自定义方法名称
一些Properties have names that do not match setter 方法.在这些情况下,某个特性可能会使用 BindingMethods 注释与 setter 相关联.注释与类一起使用,可以包含多个 BindingMethod 注释,每个注释对应一个重命名的方法.绑定方法是可添加到应用中任何类的注释.在以下示例中,android:tint 属性与 setImageTintList(ColorStateList) 方法相关联,而不与 setTint() 方法相关联
/**
* Applies a tint to the image drawable. Does not modify the current tint
* mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
* <p>
* Subsequent calls to {@link #setImageDrawable(Drawable)} will automatically
* mutate the drawable and apply the specified tint and tint mode using
* {@link Drawable#setTintList(ColorStateList)}.
* <p>
* <em>Note:</em> The default tint mode used by this setter is NOT
* consistent with the default tint mode used by the
* {@link android.R.styleable#ImageView_tint android:tint}
* attribute. If the {@code android:tint} attribute is specified, the
* default tint mode will be set to {@link PorterDuff.Mode#SRC_ATOP} to
* ensure consistency with earlier versions of the platform.
*
* @param tint the tint to apply, may be {@code null} to clear tint
*
* @attr ref android.R.styleable#ImageView_tint
* @see #getImageTintList()
* @see Drawable#setTintList(ColorStateList)
*/
@android.view.RemotableViewMethod
public void setImageTintList(@Nullable ColorStateList tint) {
mDrawableTintList = tint;
mHasDrawableTint = true;
applyImageTint();
}
BindingTintMethods
package com.anniljing.jetpackviewmodel.util
import android.widget.ImageView
import androidx.databinding.BindingMethod
import androidx.databinding.BindingMethods
@BindingMethods(value = [
BindingMethod(
type = ImageView::class,
attribute = "tint",
method = "setImageTintList")])
class BindingTintMethods {
}
activity_observable_binding_methods
<?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">
<data>
<variable
name="user"
type="com.anniljing.jetpackviewmodel.model.ObservableUser" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{Integer.toString(user.like)}"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_whatshot_black_96dp"
app:tint="@{user.like > 9 ? @color/star : @android:color/black}" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Like"
android:onClick="addLike"/>
</LinearLayout>
</layout>
ObservableBindingMethodsActivity
package com.anniljing.jetpackviewmodel.activity
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.databinding.ObservableInt
import com.anniljing.jetpackviewmodel.R
import com.anniljing.jetpackviewmodel.databinding.ActivityObservableBindingMethodsBinding
import com.anniljing.jetpackviewmodel.model.ObservableUser
class ObservableBindingMethodsActivity : AppCompatActivity() {
private val user: ObservableUser by lazy {
ObservableUser("张三", ObservableInt(2))
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityObservableBindingMethodsBinding =
DataBindingUtil.setContentView(this, R.layout.activity_observable_binding_methods)
binding.user = user
}
fun addLike(view: View) {
user.like.set(user.like.get() + 1)
}
}


提供自定义逻辑
一些属性需要自定义绑定逻辑,Android 框架类的特性已经创建了 BindingAdapter 注释.If we want to take the above exampletint属性和srcProperties are implemented via a custom property:
ObservableBindingAdapterUser
package com.anniljing.jetpackviewmodel.model
import androidx.databinding.ObservableInt
class ObservableBindingAdapterUser {
var like: ObservableInt = ObservableInt(0)
set(value) {
field = value
}
var popularity: ObservableInt by ::like
}
BindingMergeAdapters
package com.anniljing.jetpackviewmodel.util
import android.content.Context
import android.content.res.ColorStateList
import android.widget.ImageView
import androidx.core.content.ContextCompat
import androidx.core.widget.ImageViewCompat
import androidx.databinding.BindingAdapter
import androidx.databinding.ObservableInt
import com.anniljing.jetpackviewmodel.R
object BindingMergeAdapters {
@BindingAdapter("mergeTintAndSrc")
@JvmStatic fun mergeTintAndSrc(imageView: ImageView, mergeType: ObservableInt){
val context:Context=imageView.context
imageView.setImageResource(R.drawable.ic_whatshot_black_96dp)
if (mergeType.get()>4){
ImageViewCompat.setImageTintList(imageView, ColorStateList.valueOf(ContextCompat.getColor(context, R.color.popular)))
}else if (mergeType.get()>9){
ImageViewCompat.setImageTintList(imageView, ColorStateList.valueOf(ContextCompat.getColor(context, R.color.star)))
}
}
}
activity_observable_binding_adapter
<?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">
<data>
<variable
name="user"
type="com.anniljing.jetpackviewmodel.model.ObservableBindingAdapterUser" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{Integer.toString(user.like)}" />
<ImageView
app:mergeTintAndSrc="@{user.popularity}"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="addLike"
android:text="Like" />
</LinearLayout>
</layout>
ObservableBindingAdapterActivity
package com.anniljing.jetpackviewmodel.activity
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import com.anniljing.jetpackviewmodel.R
import com.anniljing.jetpackviewmodel.databinding.ActivityObservableBindingAdapterBinding
import com.anniljing.jetpackviewmodel.model.ObservableBindingAdapterUser
class ObservableBindingAdapterActivity : AppCompatActivity() {
private val observableUser: ObservableBindingAdapterUser by lazy {
ObservableBindingAdapterUser()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityObservableBindingAdapterBinding =
DataBindingUtil.setContentView(this, R.layout.activity_observable_binding_adapter)
binding.user = observableUser
}
fun addLike(view: View) {
observableUser.like.set(observableUser.like.get() + 1)
}
}
边栏推荐
猜你喜欢

经纬度求距离

USB URB

STM32学习笔记(白话文理解版)—按键控制

USB 枚举过程中8 字节标准请求解析

精彩联动 | OpenMLDB Pulsar Connector原理和实操
![[Meetup] OpenMLDBxDolphinScheduler engineering and scheduling link link characteristics, building the end-to-end MLOps workflow](/img/d8/a367c26b51d9dbaf53bf4fe2a13917.png)
[Meetup] OpenMLDBxDolphinScheduler engineering and scheduling link link characteristics, building the end-to-end MLOps workflow

OpenMLDB Pulsar Connector: Efficiently connect real-time data to feature engineering

华为云IOT平台设备获取api调用笔记

Visual studio2019 configuration uses pthread

STM32学习笔记(白话文理解版)—搞懂PWM输出
随机推荐
Asp doNet Mvc4绑定js脚本用法
Jetpack之dataBinding
Visual studio2019 configuration uses pthread
实时特征计算平台架构方法论和基于 OpenMLDB 的实践
He Kaiming's new work ViTDET: target detection field, subverting the concept of layered backbone
MSP430学习总结(二)——GPIO
OpenMLDB + Jupyter Notebook: Quickly Build Machine Learning Applications
Open Source Machine Learning Database OpenMLDB Contributor Program Fully Launched
vscode插件开发——代码提示、代码补全、代码分析
C语言中switch的嵌套
SearchGuard configuration
产品经理与演员有着天然的相似
如何快速转行做产品经理
promise.all 学习(多个promise对象回调)
promise 改变状态的方法和promise 的then方法
net6 的Web MVC项目中事务功能的应用
STM32学习笔记(白话文理解版)—USART通信接口
STM32学习总结(二)——GPIO
scanf函数在混合接受数据(%d和%c相连接)时候的方式
js学习进阶BOM部分(pink老师笔记)