1.官方文档

  https://developer.android.com/topic/libraries/data-binding/binding-adapters

  https://developer.android.com/topic/libraries/data-binding/two-wa

2.自定义绑定

2.1 系统定义的绑定方法

  假设在绑定布局文件中使用app:aaaaa 的属性,绑定库自动尝试查找方法 setAaaaa(arg)。

  • 按app:aaaaa 时传递的参数, 找到参数匹配或兼容的那个方法setAaaaa
  • 不会考虑属性的命名空间
  • 搜索方法时仅使用属性名称和类型
  • 假设类Student包含 setTtttt 这个方法,那么可以直接在布局文件中使用 app:ttttt 这个属性。

2.2 自定义绑定的方法

  • a.重新绑定属性与对应的方法

         @BindingMethods(value = [
    BindingMethod(
    type = ImageView::class,
    attribute = "android:tint",
    method = "setImageTintList")])

上述代码把 android:tint 这个属性绑定到了setImageTintList方法。官方文档中并没有给出这段应该放哪里,放在类里面编译不过,通过官方完整示例中发现它是全局的。

  • b.修改系统已经定义好的方法

             @androidx.databinding.BindingAdapter("android:paddingLeft")
    @JvmStatic
    fun setPaddingLeft(view: View, oldPadding: Int, newPadding: Int) {
    if (oldPadding != newPadding) {
    view.setPadding(,
    view.getPaddingTop(),
    view.getPaddingRight(),
    view.getPaddingBottom())
    }
    }

    重新定义了 android:paddingLeft属性,注意,调用的时候  android:paddingLeft='@{16}' 才匹配这个方法,android:paddingLeft="16dp" 还是系统的那个方法。

   出现冲突时,自定义的绑定方法会替换数据绑定库提供的默认方法.

   重新定义系统已经存在的属性没意义,这个方法要以 '@{16}‘ 这种 方式调用,android:paddingLeft="16dp" 无效

  • c.把多个属性联合在一起,绑定个方法

             @JvmStatic
    @androidx.databinding.BindingAdapter(value = ["imageUrl", "error"], requireAll = false)
    fun loadImage(view: ImageView, url: String, error: Drawable) {
    Picasso.get().load(url).error(error).into(view)
    }

    requireAll = false 的含义是 单独使用imageUrl,error其中一个属性的时候,就绑定这个方法,true就是必需同时使用这两个属性的时候才绑定这个方法。

    使用

    <ImageView
    android:id="@+id/imageView2"
    android:layout_width="64dp"
    android:layout_height="64dp"
    app:error='@{@drawable/error}'
    app:imageUrl='@{"sdfsd.com/fef.ppppjnpng"}'
    />

2.3 类型转换 @BindingConversion

作用:使用这个 注解可以定义一个类型A到类型B在转换函数,函数名的格式为

convertAToB,如 convertStringToData
         @JvmStatic
@androidx.databinding.BindingConversion
fun convertStringToData(name : String) = Data()

3. 双向绑定

3.1 单向的问题

  默认是单向绑定,控件与用户的交互(如输入新的名字,点单选框和复选框)不会自动修改对应的绑定数据对象,要在代码里手动处理相应的控件事件,在事件函数里修改数据对象。如:

     val data = Data()
lateinit var binding : Way2Binding
val nameWatcher = object : TextWatcher{
override fun afterTextChanged(p0: Editable?) {
val txt = p0.toString()
data.name = txt
binding.invalidateAll()
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
} fun initBinding(){
binding.data = data
binding.normalEdt.addTextChangedListener(nameWatcher)
}

3.2 使用双向绑定

  使用双向绑定可以简化这个问题,减少相应代码。

  用 @={} 表示可接收属性的数据更改并同时监听用户更新.

       <EditText
...
android:text='@={data.name,default=@string/data_name}'
.../>

  这样当用户在这个EditText上输入新的内容后,直接更新到绑定的数据对象。

  注意: @={} 不可以使用格式化的@string/xx   

3.3 自定义的属性使用双向绑定

a.自定义属性的 setXXX

     @BindingAdapter("dataName")
@JvmStatic fun setDataName(edt : EditText, txt : String){
edt.setText(txt)
}

b.自定义属性的 getXXX

     @InverseBindingAdapter(attribute = "dataName")
@JvmStatic fun getDataName(edt : EditText) : String{
return edt.text.toString()
}

注意:attribute =  不可少,否则编译不过。

c.编写属性变化监听器及想要监听的事件

     @BindingAdapter("dataNameAttrChanged")
@JvmStatic fun setListener(edit : EditText, listener: InverseBindingListener?) {
Log.e("dataNameAttrChanged","txt = ${edit.text.toString()}")
var txt = ""
edit.addTextChangedListener(object : TextWatcher{
override fun afterTextChanged(p0: Editable?) {
Log.e("dataNameAttrChanged","afterTextChanged")
if (txt != p0.toString()){
listener?.onChange()
txt = p0.toString()
}
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
})
}
  • InverseBindingListener 是属性变化监听器
  • 这个 EditText 监听的事件是 textChanged

注意:  listener?.onChange() 容易死 循环,要判断下原内容与新内容,不一样才调用这个函数。上述代码中的高亮部分。

d.布局文件中使用

    <EditText  app:dataName='@={data.name}'  ... >

3.4 类型转换的双向绑定

使用类型转换时,也可以使用双向绑定,但是要指定一个反向转换的函数。用 @InverseMethod("转换函数名") 来声明。

 @file:JvmName("Converter")

 package com.example.databind
import androidx.databinding.InverseMethod class A (var name: String) @InverseMethod("a2String")
fun string2a(string: String) : A{
return A(string)
} fun a2String(a : A) : String{
return a.name
}

在布局文件中

    <EditText android:text='@={Converter.a2String(a)}' />

3.5 支持双向绑定的内置属性

控件 属性 绑定适配器所在的类
AdapterView android:selectedItemPosition
android:selection
AdapterViewBindingAdapter
CalendarView android:date CalendarViewBindingAdapter
CompoundButton android:checked CompoundButtonBindingAdapter
DatePicker android:year
android:month
android:day
DatePickerBindingAdapter
NumberPicker android:value NumberPickerBindingAdapter
RadioButton android:checkedButton RadioGroupBindingAdapter
RatingBar android:rating RatingBarBindingAdapter
SeekBar android:progress SeekBarBindingAdapter
TabHost android:currentTab TabHostBindingAdapter
TextView android:text TextViewBindingAdapter
TimePicker android:hour
android:minute
TimePickerBindingAdapte

 

android 数据绑定(6)自定义绑定方法、双向数据绑定的更多相关文章

  1. 【Angular 5】数据绑定、事件绑定和双向绑定

    本文为Angular5的学习笔记,IDE使用Visual Studio Code,内容是关于数据绑定,包括Property Binding.Class Binding.Style Binding. 在 ...

  2. 2-4 Vue中的属性绑定和双向数据绑定

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. Vue学习之vue属性绑定和双向数据绑定

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. angular 双向数据绑定与vue数据的双向数据绑定

    二者都是 MVVM 模式开发的典型代表 angular 是通过脏检测实现,angular 会将 UI 事件,请求事件,settimeout 这类延迟的对象放入到事件监测的脏队列,当数据变化的时候,触发 ...

  5. Angularjs进阶笔记(2)-自定义指令中的数据绑定

    有关自定义指令的scope参数,网上很多文章都在讲这3种绑定方式实现的效果是什么,但几乎没有人讲到底怎么使用,本篇希望聊聊到底怎么用这个话题. 一. 自定义指令 自定义指令,是Angularjs用来实 ...

  6. angularJs初体验,实现双向数据绑定!使用体会:比较爽

    使用初体验:ng 双向数据绑定: 最简单的双向数据绑定:(使用默认模块控制) <body ng-app> <input type="text" ng-model= ...

  7. 组件使用v-model、$listeners、.sync(区别于v-model的双向数据绑定)

    自定义组件 自定义组件的v-model 首先我们先说一下在自定义组件中使用v-model的必要条件 在自定义的组件中要有input(这里我们先不讨论单选复选框) 在自定义组件的模板对象中要有props ...

  8. vue 双向数据绑定的实现学习(一)

    前言:本系列学习笔记从以下几个点展开 什么是双向数据绑定 双向数据绑定的好处 怎么实现双向数据绑定 实现双向数据数据绑定需要哪些知识点 数据劫持 发布订阅模式 先看看我们要实现的目标是什么,如下动图: ...

  9. ng 双向数据绑定

    1.方向1:model->View模型数据绑定到视图 绑定的方式:①双花括号 ②常见的ng指令(ngRepeat ngIf ngShow....) 效果:数据一旦绑定到视图上,随着数据的修改,视 ...

随机推荐

  1. .NetCore 入门

    .net core是什么? .net core是一个可以用来构建现代.可伸缩和高性能的跨平台软件应用程序的通用开发框架. 我们为什么要使用.net core,也就是说.net core有什么好处? 跨 ...

  2. python6.2类的封装

    class Card(object): def __init__(self,num,pwd,ban): self.num=num#卡号 self.pwd=pwd#密码 self.__ban=ban#余 ...

  3. 039_go语言中的排序

    代码演示: package main import "fmt" import "sort" func main() { strs := []string{&qu ...

  4. docker,容器,编排,和基于容器的系统设计模式

    目录 从容器说起 背景 docker实现原理 编排之争 基于容器的分布式系统设计之道 单节点协作模式 Sidecar pattern(边车模式) Ambassador pattern(外交官模式) A ...

  5. C#LeetCode刷题之#66-加一(Plus One)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3684 访问. 给定一个由整数组成的非空数组所表示的非负整数,在该 ...

  6. 滴滴推理引擎IFX:千万规模设备下AI部署实践

    桔妹导读:「滴滴技术」将于本月开始,联合各技术团队为大家带来精彩分享.你想了解的技术干货,深度专访,团队及招聘将于每周三与你准时见面.本月为「滴滴云平台事业群分享月」,在今天的内容中,云平台事业群-机 ...

  7. 用python爬取B站在线用户人数

    最近在自学Python爬虫,所以想练一下手,用python来爬取B站在线人数,应该可以拿来小小分析一下 设计思路 首先查看网页源代码,找到相应的html,然后利用各种工具(BeautifulSoup或 ...

  8. 存储系列之 VFS虚拟文件系统简介

    引言:文件系统发展到一定阶段,开始进一步抽象和分层.   前面我们介绍了ext系列文件系统和xfs文件系统,这些是Linux使用最多的文件系统,也是很多发布版本默认选择的文件系统.而事实上,Linux ...

  9. 学习Python(新手教程链接)

    1.这个是地址: https://www.ggdoc.com/cHl0aG9uIG1zaeaYr_S7gOS5iA2/NTY4Nzc1MWQxMDJkZTJiZDk3MDU4OGE20/

  10. 记录使用Python登录浙江大学统一身份认证

    背景 现在每天要进行健康情况上报,但是因为经常睡过头忘记打卡,于是想着写一个程序来自动打卡. 统一身份认证 访问健康情况上报页面(https://healthreport.zju.edu.cn/nco ...