BataBinding

张开发
2026/4/17 19:13:32 15 分钟阅读

分享文章

BataBinding
DataBindingViiewModel、LiveData、ViewDataBinding三者结合DataBinding能够让UI自动响应数据的变化而不需要手动更新UI。方式如下在ViiewModel中分别使用LiveData存储各项数据将ViewMode定义设置为ViewDataBinding中的变量在ViewDataBinding中将ViewModel中的LiveData分别绑定给各个控件并将ViewDataBinding的lifecycleOwner设置为Activity 或 Fragment 实例的生命周期这确保 ViewDataBinding 能正确观察 ViewModel 数据变化及时更新视图。ViewBindingdata binding实际分为data binding(数据绑定和view binding(视图绑定两部分。视图绑定是解决麻烦的findViewById的数据绑定是提供数据和xml双向绑定的。数据绑定‌表达式语法数据绑定的一些用法使用{}包裹表达式如android:text{user.name}。支持空值安全若user为nulluser.name不会崩溃而是返回默认值如null或0。‌空合并操作符‌android:text{user.displayName ?? user.lastName}等价于user.displayName ! null ? user.displayName : user.lastName。Null Coalescing 空合并运算符??会取第一个不为 null 的值作为返回值。‌三元运算符‌android:text{user.isActive ? string/active : string/inactive}。android:text{user.name,defaultabc}。‌字符串资源‌android:text{string/app_name(各占位符内容)}。dimension资源android:textSize{dimen/sp11}。‌集合访问‌Map{map[key]}或{map[key]}List{list[index]}。onClick事件绑定onClick“{()-data.setXXX(context)}”传参context即本控件的context。onClick“{Class1::fun1}”静态方法调用。layout_width不可使用绑定语法主代码中绑定xml使用xxBinding.inflatesetContentViewval binding:ActivityAboutBinding ActivityAboutBinding.inflate(layoutInflater) setContentView(binding.root)使用DataBindingUtil.setContentViewval binding DataBindingUtil.setContentViewActivityAboutBinding(this, R.layout.activity_about)使用DataBindingUtil.inflatesetContentViewval binding: CustomerListItemBinding DataBindingUtil.inflate(LayoutInflater.from(parent.context), layoutId, parent, false) setContentView(binding.root)在RecyclerViewHolder绑定中使用executePendingBindingsval binding: CustomerListItemBinding? DataBindingUtil.getBinding((holder.itemView as ViewGroup).getChildAt(0)) binding?.datacustomer binding?.executePendingBindings()扩展View属性配置BindingAdapter注解如果绑定数据提供的参数不符合配置类型或需要比代码更方便的参数配置则可以给View增加属性配置。以前需要在自定义View并在构造函数中解析新属性而现在可以使用DataBinding直接定义注解静态方法在此方法内实现配置的作用即可。使用BindingAdapter注解标记在public static方法上可将多个参数在注解中value中配置和方法中的形参名一一对应。requireAll true表示配置的所有属性在xml中都同时使用才会调用到该方法否则只要有一个属性被使用就能调用到该方法。public class Util{ BindingAdapter(value {“image_url”, “isCircle”, “radius”}, requireAll false) public static void setImageUrl(ImageView view, String imageUrl, boolean isCircle,int radius) { view.setImageUrl(view, imageUrl, isCircle, 0); } }BindingAdapter(marginStart2) fun setLayoutMarginStart2(view: ImageView, margin: Float) { val l(view.layoutParams as ViewGroup.MarginLayoutParams) l.marginStart LayoutUtil.dip2px(view.context,margin) view.layoutParamsl }在布局文件中控件上使用app命名空间逐个使用绑定语法配置新属性值。ImageView app:image_url “{user.avatar}” app:radius“{50}”/还可以直接给View重写android属性配置例如BindingAdapter(android:textColor,requireAllfalse) fun setTextColor(view: TextView, type:Int) { val colorwhen(type){ 1-R.color.color1 else-R.color.color2 } view.setTextColor(view.context.resources.getColor(color)) }BindingConversion注解BindingConversion用于‌自动类型转换‌当布局中绑定的表达式类型与目标属性所需类型不匹配时DataBinding 会查找带有该注解的方法进行转换。BindingConversion fun converString2Color(str:String):Drawable { return when(str){ red-ColorDrawable(Color.RED) else-ColorDrawable(Color.BLACK) } }推荐优先使用BindingAdapter实现复杂逻辑BindingConversion仅用于简单、安全的类型转换‌。事件绑定事件绑定设置的是回调接口。事件绑定有多种方式方法引用。{viewModel.fun1}或{viewModel::fun1}需保持事件回调方法的签名一致即方法参数和返回值必须和原始的回调函数保持一致。Lambda 表达式{()-viewModel.fun1()}可以不遵循默认的方法签名。自定义事件绑定只要控件中有设置事件接口的方法就可以在视图配置文件中使用绑定自定义事件。include绑定当include标签中的layout属性值是binding类型时可以在include标签中给其绑定类型绑定值。include layoutlayout/layout1 android:idid/skinRecognize app:data1{data2}/include标签的命名规则跟View的命名规则是一样的: include标签的id被当作成员变量名. 被include的layout文件会生成一个自己的类, 里面的view也会被赋值给成员变量.记住要给include标签一个id, 否则不会为其生成公共成员变量. 同时,记住在外面使用 layout 标签. 这回触发预处理过程, 生成类并绑定view.如果你去查看生成的类, 会发现无论被include多少次, 他们使用的都是同一个类。其它绑定BindingMethods注解InverseBindingAdapter反向绑定。LiveData和BaseObservable的用法区别LiveData可直接绑定到ViewDataBinding中的控件BaseObservable是其中的成员变量绑定到控件上。LiveData可自动更新控件BaseObservable需要通知属性改变。BaseObservableBaseObservable也是Android Jetpack库的一部分它主要用于实现数据绑定中对象的属性变化通知机制。它通常与Bindable注解一起使用以便在属性变化时自动通知UI进行更新。BaseObservable类位于androidx.databinding包中。从Android Jetpack的2.0版本开始推荐使用LiveData和DataBinding库的组合方式而不是直接使用BaseObservable。ObservableField、ObservableIntLiveDataLiveData组件是Jetpack推出的基于观察者的消息订阅/分发组件,具有宿主(Activity、Fragment)生命周期感知能力,这种感知能力可确保LiveData仅分发消息给处于活跃状态的观察者。LiveData的消息分发机制,是以往的Handler,EventBus、RxjavaBus无法比拟的,它们不论当前页面是否可见,有消息就转发。导致即便应用在后台页面不可见,还在做一些无用的绘制计算(可以发现微信消息列表是在可见状态时才会更新列表最新信息的)。活跃状态是指Observer所在的宿主处于started,resumed状态。Transformations.map()可以对LiveData进行映射变化并返回一个新的LiveData。sMutableLiveData、MediatorLiveDataSwitchMap黏性消息分发即新注册的observer也能接收到前面发送的最后一条数据。

更多文章