双向绑定的实现原理与样板代码

2024-05-04 10:48

本文主要是介绍双向绑定的实现原理与样板代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

双向绑定的方法有几种这里用到的是借助@BindingAdapter来实现。无项
就是xml里面有一个model,你设置进去了,它就更新就是了。纯单项 ,所谓单项 ,就是你调用一个值set就可以让view变化,这需要@Bindable@ notifyPropertyChanged(BR.title);双项是值 可以修改值来改变view的状态 或者通过修改view的状态来实现修改model的值 这就是你中有我我中有你.

model继承extends BaseObservable
然后set里面设置
这需要@BindingAdapter @InverseBindingAdapter
@BindingAdapter是方便xml里面设置用的。 比如里面定义 @BindingAdapter("intvalue")就可以使用xxx:@{xxx.xx}

class BBB extends BaseObservable{@Bindable//有了注解这个才会生成BR.titlepublic String getTitle() {return title;}public void setTitle(String title) {this.title = title;notifyPropertyChanged(BR.title);//双向绑定通知改变,不通知就不会生效。}
}

单项绑定的我不想再说了,直接上高阶代码

下面代码实现 int类型编辑框的双向生效,修改编辑框内容的时候model值变化,修改model值得时候编辑框内容变化。

任意创建一个类定义下面几个静态方法

第一个方法代表 修改view,

@BindingAdapter("intvalue")public static void setTextIntValue(TextView view, int value) {

第二个方法代表修改model

@InverseBindingAdapter(attribute = "intvalue", event = "intvalueAttrChanged")public static int getTextIntValue(TextView view) {

第三个方法代表修改model的触发条件在里面设置view监听然后调用onChange从而触发调用第二个方法。

@InverseBindingAdapter(attribute = "intvalue", event = "intvalueAttrChanged")

第二个方法的event对应的是第三个方法的@BindingAdapter("intvalueAttrChanged")

用法:
在xml里面定义

<EditTextapp:intvalue="@={model.age}"
/>

触发原理:
编译后会生成一个databindimpl,它会根据注解生成viewbinding生成一个类,
里面的代码就是把第三个方法的代码拷贝一份进行设置监听,
当你修改编辑框内容的时候监听触发了,onChange,onChange()这是代表view改变,我之前说过是会通知model改变,model的改变为第二个方法,getxxint ,你可以尝试写死一个值,你会发现这个值在model里面生效了。

当你通过set器修改model的值,通过model里面定义的

notifyPropertyChanged(BR.title);/

就会触发view的修改,但是这里是个死循环,
这双向绑定不需要加notifyPropertyChanged(BR.title);或者加一个判断,
当然我这里之所以还是加上了,是我监听的不对,我写在了onTextChanged里面。
直接不加上notifyPropertyChanged也能修改,但是光标位置不对,感觉不太爽,所以解决方法就是调整一下回调通知或者不加判断。

/*** 根据model的值来设置 view的值 双向绑定 ,setValue Model 不需要加notifyFieldChanage() 否则死循环 除非文本判断。**/@BindingAdapter("intvalue")public static void setTextIntValue(TextView view, int value) {
//        final TextWatcher oldValue = ListenerUtil.trackListener(view, null, R.id.textWatcher);if(ParseUtil.parseInt(view.getText().toString()) ==value){//0 or "" ==0 找到死循环的原因了,现在不需要加这句话了。return;}if(value==0){view.setText("");//可以在失去焦点的时候设置。}else{view.setText(value + "");}
//        if(oldValue!=null){
//        view.addTextChangedListener(oldValue);}/*** 在onChange 里面调用本方法获得返回值, 然后来修改模型的值.** @param view* @return*/@InverseBindingAdapter(attribute = "intvalue", event = "intvalueAttrChanged")public static int getTextIntValue(TextView view) {return ParseUtil.parseInt(view.getText().toString());}@BindingAdapter("intvalueAttrChanged")public static void intValueChangeBind(final TextView view,final InverseBindingListener changeBindListener) {TextWatcher watcher =null;if(changeBindListener!=null){watcher = new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence s, int start, int count, int after) {}@Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {changeBindListener.onChange();}@Overridepublic void afterTextChanged(Editable s) {}};}else{}
//            view.addTextChangedListener(watcher);//下面的话没有任何意义 //下面的话加不加都解决不了死循环的问题 只能用判断来解决死循环 addTextChangedListener可能是这句话导致final TextWatcher oldValue = ListenerUtil.trackListener(view, watcher, R.id.textWatcher);if (oldValue != null) {view.removeTextChangedListener(oldValue);}if (watcher != null) {view.addTextChangedListener(watcher);}}

更多databind请访问我的其它文章。

这篇关于双向绑定的实现原理与样板代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/959026

相关文章

Spring Boot整合Redis注解实现增删改查功能(Redis注解使用)

《SpringBoot整合Redis注解实现增删改查功能(Redis注解使用)》文章介绍了如何使用SpringBoot整合Redis注解实现增删改查功能,包括配置、实体类、Repository、Se... 目录配置Redis连接定义实体类创建Repository接口增删改查操作示例插入数据查询数据删除数据更

Java Lettuce 客户端入门到生产的实现步骤

《JavaLettuce客户端入门到生产的实现步骤》本文主要介绍了JavaLettuce客户端入门到生产的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 目录1 安装依赖MavenGradle2 最小化连接示例3 核心特性速览4 生产环境配置建议5 常见问题

linux ssh如何实现增加访问端口

《linuxssh如何实现增加访问端口》Linux中SSH默认使用22端口,为了增强安全性或满足特定需求,可以通过修改SSH配置来增加或更改SSH访问端口,具体步骤包括修改SSH配置文件、增加或修改... 目录1. 修改 SSH 配置文件2. 增加或修改端口3. 保存并退出编辑器4. 更新防火墙规则使用uf

Java 的ArrayList集合底层实现与最佳实践

《Java的ArrayList集合底层实现与最佳实践》本文主要介绍了Java的ArrayList集合类的核心概念、底层实现、关键成员变量、初始化机制、容量演变、扩容机制、性能分析、核心方法源码解析、... 目录1. 核心概念与底层实现1.1 ArrayList 的本质1.1.1 底层数据结构JDK 1.7

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node