Android DataBinding 自定义View实现数据双向绑定
看不懂的可以先看看单向数据绑定:Android DataBinding数据变化时自动更新界面_皮皮高的博客-CSDN博客
然后再确定已经启动了dataBinding的情况下,按下面的顺序来:
首先创建一个自定义View:
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.util.AttributeSet
import android.view.Viewclass MyView(context: Context, attr: AttributeSet) : View(context, attr) {var number = 0set(value) {field = valueinvalidate()}private val onNumberChangeListenerList = ArrayList<OnNumberChangeListener>()private val paint = Paint()init {setOnClickListener {number ++invalidate()for (item in onNumberChangeListenerList) {item.onChange(number)}}}override fun onDraw(canvas: Canvas?) {super.onDraw(canvas)canvas!!paint.color = Color.REDcanvas.drawRect(Rect(0, 0, width, height), paint)paint.color = Color.YELLOWpaint.textSize = resources.displayMetrics.density * 20canvas.drawText(number.toString(), width / 2f, height / 2f, paint)}fun addOnNumberChangeListener(listener: OnNumberChangeListener) {onNumberChangeListenerList.add(listener)}fun removeOnNumberChangeListener(listener: OnNumberChangeListener) {onNumberChangeListenerList.remove(listener)}interface OnNumberChangeListener {fun onChange(number: Int)}}
代码很简单,就是在界面上显示一个矩形,然后里面有个文本,用来显示被点击了多少次。
接着实现双向数据绑定逻辑:
import androidx.databinding.BindingAdapter
import androidx.databinding.InverseBindingAdapter
import androidx.databinding.InverseBindingListener
import androidx.databinding.adapters.ListenerUtilobject ViewAdapter {@BindingAdapter("number")@JvmStatic fun setNumber(view: MyView, number: Int){if (view.number == number) {return}view.number = number}@InverseBindingAdapter(attribute = "number")@JvmStatic fun getNumber(view: MyView): Int{return view.number}@BindingAdapter("numberAttrChanged")@JvmStatic fun setNumberListener(view : MyView, listener: InverseBindingListener?) {val newListener = object : MyView.OnNumberChangeListener {override fun onChange(number: Int) {listener?.onChange()}}val oldListener = ListenerUtil.trackListener(view, newListener, R.id.onNumberChangeListener)oldListener?.apply {view.removeOnNumberChangeListener(this)}view.addOnNumberChangeListener(newListener)}}
总的来说只要实现三个方法就行了,现在来说下每个方法的含义:
setNumber() 用于把数据设置到View上,这里还需要添加判断数据是否重复,重复了就return,不然有概率会死循环
getNumber() 用于给框架提供数据,也就是要返回用于数据双向绑定的值。
setNumberListener() 用于给框架设置数据变化监听,当监听到变化时,框架就会调用getNumber()来获取数据并应用到ViewMode上。(方法内部调用了一个ListenerUtil.trackListener()方法,这是官方的推荐的写法,用于监听器类型是集合的情况下,如果是set/get之类的那就直接set新的监听器即可。)
然后创建ViewMode:
import androidx.databinding.ObservableFieldclass UserObservable {val number: ObservableField<Int> by lazy {ObservableField<Int>()}}
创建Activity,并实现一些基础的显示逻辑:
import android.app.Activity
import android.os.Bundle
import android.view.View
import androidx.databinding.DataBindingUtil
import com.cc.databingdingtest.databinding.MainBindingclass MainActivity: Activity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)val binding: MainBinding = DataBindingUtil.setContentView(this, R.layout.main)val userViewMode = UserObservable()userViewMode.number.set(0)binding.user = userViewModefindViewById<View>(android.R.id.content).setOnClickListener {userViewMode.number.set(1000)}}}
测试一下:
先点击View,然后打断点看看ViewMode里的数据是否会变化。

成功。
然后再看看修改ViewMode数据是否能自动应用到界面上

成功的实现了双向数据绑定 。
相关文章:
Android DataBinding 自定义View实现数据双向绑定
看不懂的可以先看看单向数据绑定:Android DataBinding数据变化时自动更新界面_皮皮高的博客-CSDN博客 然后再确定已经启动了dataBinding的情况下,按下面的顺序来: 首先创建一个自定义View: import android.content.Context imp…...
网络安全中的渗透测试主要那几个方面
渗透测试中主要有软件测试和渗透测试。 1、测试对象不同 软件测试:主要测试的是程序、数据、文档。 渗透测试:对象主要为网络设备、主机操作系统、数据库系统和应用系统。 2、测试内容不同 软件测试:主要工作内容是验证和确认,发…...
Cursor:GPT-4 驱动的强大代码编辑器
Cursor (https://www.cursor.so/)是 GPT-4 驱动的一款强大代码编辑器,可以辅助程序员进行日常的编码。下面通过一个实际的例子来展示 Cursor 如何帮助你编程。这个例子做的事情是网页抓取。抓取的目标是百度首页上的百度热搜,如下…...
C/C++中for语句循环用法及练习
目录 语法 下面是 for 循环的控制流: 实例 基于范围的for循环(C11) 随堂笔记! C语言训练-计算1~N之间所有奇数之和 题目描述 输入格式 输出格式 样例输入 样例输出 环形方阵 干货直达 for 循环允许您编写一个执行特定次数的循环的重复控制结构。…...
AnimatorOverrideController说明
unity-AnimatorOverrideControllerhttps://docs.unity.cn/cn/current/ScriptReference/AnimatorOverrideController.html 用于控制动画器重写控制器的接口。 动画器重写控制器的用途是重写某个控制器的动画剪辑,从而为给定化身定制动画。 在运行时基于相同的 Anim…...
1.4、第三阶段 MySQL数据库
root数据库技术 一、数据库理论 1 什么是数据库技术 数据库技术主要研究如何组织、存储数据,并如何高效地提取和处理数据。 2 什么是SQL SQL(Structured Query Language)结构化查询语言 SQL是操作数据库的命令集,也是功能齐全的…...
LeetCode:202. 快乐数
🍎道阻且长,行则将至。🍓 🌻算法,不如说它是一种思考方式🍀算法专栏: 👉🏻123 一、🌱202. 快乐数 题目描述:编写一个算法来判断一个数 n 是不是快…...
Android 14 新功能之 HighLights:快速实现文本高亮~
日常开发中可能会遇到给 TextView 的全部或部分文本增加高亮效果的需求,以前可能是通过 Spannable 或者 Html 标签实现。 升级 Android 14 后就不用这么迂回了,因其首次引入直接设置高亮的 API:HighLights。需要留意的是 HighLights API 和 …...
[渗透教程]-004-嗅探工具-Nmap
文章目录 Nmap介绍基本操作进阶操作Nmap介绍 nmap是一个网络扫描和主机检测工具,它可以帮助用户识别网络上的设备和服务。获取主机正在运行哪些服务,nmap支持多种扫描,UDP,TCP connect(),TCP SYN(半开扫描) ftp代理,反向标志,ICMP,FIN,ACK扫描,ftp代理,反向标志,ICMP. 可以用于…...
大数据技术之Hive SQL题库-初级
第一章环境准备1.1 建表语句hive>-- 创建学生表 DROP TABLE IF EXISTS student; create table if not exists student_info(stu_id string COMMENT 学生id,stu_name string COMMENT 学生姓名,birthday string COMMENT 出生日期,sex string COMMENT 性别 ) row format delim…...
常见HTTP状态码汇总
文章目录1xx: 信息2xx: 成功3xx: 重定向4xx: 客户端错误5xx: 服务器错误1xx: 信息 状态码描述100 Continue服务器仅接收到部分请求,但是一旦服务器并没有拒绝该请求,客户端应该继续发送其余的请求。101 Switching Protocols服务器转换协议:服…...
蓝桥杯刷题冲刺 | 倒计时15天
作者:指针不指南吗 专栏:蓝桥杯倒计时冲刺 🐾马上就要蓝桥杯了,最后的这几天尤为重要,不可懈怠哦🐾 文章目录1.年号字串2.裁纸刀3.猜生日1.年号字串 题目 链接: 年号字串 - 蓝桥云课 (lanqiao.c…...
【差分数组】
差分数组一维差分差分数组的作用差分矩阵结语一维差分 输入一个长度为 n 的整数序列。接下来输入 m个操作,每个操作包含三个整数 l,r,c,表示将序列中 [l,r] 之间的每个数加上 c ,请你输出进行完所有操作后的序列。 输入格式 第一行包含两个…...
2022年NOC软件创意编程(学而思)决赛小学高年级组scratch
2022NOC决赛图形化小高组 一、选择题 1.运行下面的程序,最终“我的变量”的值是多少? 2.希望定义一个函数如下,可以让角色旋转指定的圈数。里面空缺的地方填上什么数字比较合适? 3.运行程序,在舞台上可以看见几个角色 ? 4.运行程序,角色会依次说什么 ? 5.我们都知…...
[JAVA]一步接一步的一起开发-图书管理系统(非常仔细,你一定能看懂)[1W字+]
目录 1.想法 2.框架的搭构 2.1图书 2.1.1Book类 2.1.2BookList类 2.2用户 2.2.1User抽象类 2.2.2AdminUser类(管理者) 2.2.3NormalUser 2.3操作 操作接口 借阅操作 删除操作 查询操作 归还图书 展示图书 退出系统 2.4小结 3.主函数的编…...
大数据周会-本周学习内容总结07
目录 01【hadoop】 1.1【编写集群分发脚本xsync】 1.2【集群部署规划】 1.3【Hadoop集群启停脚本】 02【HDFS】 2.1【HDFS的API操作】 03【MapReduce】 3.1【P077- WordCount案例】 3.2【P097-自定义分区案例】 历史总结 01【hadoop】 1.1【编写集群分发脚本xsync】…...
搭建一个双系统个人服务器
搭建一个双系统个人服务器0.前言一、双系统安装1.磁盘划分2.windows安装3.ubuntu安装二、系统启动项美化:1. refind引导2. 美化 grub 界面三、系统代理0.前言 年后找了份工作,忙于适应新环境所以更新也减缓了,最近闲暇时间给个人电脑进行了整…...
电脑长按电源键强行关机,对SSD有伤害吗?SSD 掉盘之殇
说到“按住电源键强制关机”的操作,想必大家都不会陌生,毕竟在电脑蓝屏或者电脑死机的时候,我们总是束手无策。而且,身边的人在遇到同样的情况时,往往都是选择长按电源键强制关机,所以当我们遇到同样的情况…...
Linux:centos内核优化详解
一、系统内核部分设置在以下文件 vim /etc/sysctl.conf 1.禁用IPV6 net.ipv6.conf.all.disable_ipv6 1 # 禁用整个系统所有接口的IPv6 net.ipv6.conf.default.disable_ipv6 1 net.ipv6.conf.lo.disable_ipv6 1 # 禁用某一个指定接口的IPv6(此处为:lo) 理想情况下,…...
链表经典OJ题合集(包含带环问题,相交问题,随机指针复制等,附动画讲解)
目录 一:前言 二:简单题目 (1)移除链表元素 (2)反转链表 (3)找链表的中间结点 (4)输入一个链表,输出该链表中倒数第k个结点 (5)合并两个有序链表 (6)相交链表 (7)判断链表是否带环 三:较难题目 (1)链表分割 (2)判断链表是否为回…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
