前言

之前写了Android数据绑定DataBinding(一)入门篇,很简单的记录了如何使用DataBinding,其初衷是想要代码中的数据发生改变,不需要繁琐的setText等操作,在最后说到了只需要将POJO继承一个BaseObservable即可,其实这只是冰山一角啦!!!

本文若有出入,请指正——来自小渣渣的颤抖

客官可移步小站查看本文http://fanjiajia.cn/2019/07/07/Android/flx1/

本文接着上一篇的内容,记录一下数据对象事件处理

数据对象(Data Object)

其实继承BaseObservable的javBean叫做数据对象,官网介绍如下:

Any plain old Java object (POJO) may be used for data binding, but modifying a POJO will not cause the UI to update. The real power of data binding can be used by giving your data objects the ability to notify when data changes. There are three different data change notification mechanisms, Observable objects, observable fields, and observable collections.
When one of these observable data object is bound to the UI and a property of the data object changes, the UI will be updated automatically.

大意是:

任何普通的Java对象(PO​​JO)都可以用于数据绑定,但修改POJO不会导致UI更新。当数据改变的时候,您的数据对象能够发出通知,这才是数据绑定的威力。有三种不同的数据更改通知机制: Observable对象,observable字段, 和observable集合.
当这些observable数据对象之一被绑定到UI并且数据对象的属性改变时,UI将被自动更新。
Observable对象

这个就是我在Android数据绑定DataBinding(一)入门篇中最后介绍的那样,将我们的Bean继承 BaseObservable,这里再贴一下code;

public class User extends BaseObservable{
private String userName;
private int age;
public User(String userName, int age) {
this.userName = userName;
this.age = age;
}
@Bindable
public String getUserName() {
return userName == null ? "" : userName;
}
public void setUserName(String userName) {
this.userName = userName;
notifyPropertyChanged(BR.userName);
}
@Bindable
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
notifyPropertyChanged(BR.age);
}
@Override
public String toString() {
return "User{" +
"userName='" + userName + '\'' +
", age=" + age +
'}';
}
}

可以看到在setter方法中调用了notifyPropertyChanged(BR.age);文档中这样介绍道:The Observable interface has a mechanism to add and remove listeners, but notifying is up to the developer. 也就是说,这种机制允许开发者自己对被监听的字段进行添加和删除,我的理解就是(看你自己想绑定那些字段)。

ObservableFields

相比于上一种方式,使用ObservableFields则可以减少许多的工作量,因为我们可以许多提供的类型,文档介绍如下:ObservableField and its siblings ObservableBoolean, ObservableByte, ObservableChar, ObservableShort, ObservableInt, ObservableLong, ObservableFloat, ObservableDouble, and ObservableParcelable.

示例:

public class People {
public ObservableField<String> name = new ObservableField<>();
public ObservableInt age = new ObservableInt();
public ObservableList<String> list = new ObservableArrayList<>();
public People(String name, int age, ArrayList<String> list) {
this.name = new ObservableField<>(name);
this.age = new ObservableInt(age);
this.list = (ObservableArrayList)list;
}
}

这样就不需要我们自己在getter上设置@binding,在setter中设置notifyPropertyChanged(int)了。

Observable 集合

官方列举了这样两个例子,ObservableArrayMapObservableArrayList,其中对ObservableArrayMap的介绍是key是String这样的类型时,是非常有用的,示例如下:

ObservableArrayMap<String, Object> user = new ObservableArrayMap<>();
user.put("firstName", "Google");
user.put("lastName", "Inc.");
user.put("age", 17);

在layout中

<data>
<import type="android.databinding.ObservableMap"/>
<variable name="user" type="ObservableMap<String, Object>"/>
</data>

<TextView
android:text='@{user["lastName"]}'
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:text='@{String.valueOf(1 + (Integer)user["age"])}'
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

我的理解就是一些集合类型的封装使用。

事件处理(Event Handling)

之前对某个View设置某种监听事件是通过setXXXX,在数据绑定中是如何实现的呢,有两种方式

  • 方法引用(Method References)
  • 监听器绑定(Listener Bindings)
方法引用(Method References)

其实这种方法在之前也使用过,较多的是button的onClick事件,通常是直接在布局中写上相应Activity中的方法即可,其实这就是方法引用,学习官网的例子,我写的demo示例如下:

  • 布局文件中
<variable
name="presenter"
type="com.jiajia.mypractisedemos.module.jetpack.JetpackActivity.Presenter"/>
......
<Button
android:text="click"
android:textAllCaps="false"
android:onClick="@{presenter.onClick}"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
  • Activity中
public class Presenter {
public void onClick(View view) {
people.name.set("啊啊啊啊啊");
Toast.makeText(JetpackActivity.this, "点击了Button",Toast.LENGTH_SHORT).show();
}
}

这里注意必须给定参数View view,即需要符合事件监听的写法。

监听器绑定(Listener Bindings)

这个说真的,没特别理解,简单整理一下,英文文档说:在方法引用中,方法的参数必须与事件监听器的参数匹配。在监听器绑定中,只有你的返回值必须与监听器的期望返回值相匹配(除非它预期为void),例如:

public class Presenter {
public void onSaveClick(Task task){}
}

然后,您可以将click事件绑定到您的类,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="task" type="com.android.example.Task" />
<variable name="presenter" type="com.android.example.Presenter" />
</data>
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent">
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
android:onClick="@{() -> presenter.onSaveClick(task)}" />
</LinearLayout>
</layout>

注意这里没有传入view参数,可能这就是与方法引用不同之处,当然也可以传啦, android:onClick="@{(view) -> presenter.onSaveClick(task)}",还有好几种,也不知道什么情况下用,也不懂,不写了,以后用到再说。我觉得就方法引用的方式用得比较多,比较太low了平时写的代码。

方法引用和监听器绑定的主要区别在于实际的监听器实现是在绑定数据时创建的,而不是在事件触发时创建的。如果您喜欢在事件发生时计算表达式,则应该使用监听器绑定。

最后

下午6点了,好饿,去食堂吃麻辣烫了!

此致,敬礼

Android数据绑定DataBinding(二)入门篇的更多相关文章

  1. Android数据绑定DataBinding(一)入门篇

    早上看到了一篇推文"还在使用繁琐的findViewById,跟着尝试了一下DataBinding,之前使用ButteKnife就已经干掉了findViewById.因为写过微信小程序,那种在 ...

  2. Android数据绑定技二,企业级开发

    PS:上一篇文章写了Databinding的简单使用,写了一个绑定textview的示例,和绑定的一些用法,估计有的人会说,之前的写的好好的,为什么要数据绑定这样的写法呢,没办法,社会在进步,当然是怎 ...

  3. Android数据绑定技术二,企业级开发

    PS:上一篇文章写了Databinding的简单使用,写了一个绑定textview的示例,和绑定的一些用法,估计有的人会说,之前的写的好好的,为什么要数据绑定这样的写法呢,没办法,社会在进步,当然是怎 ...

  4. 在android 上 使用 rxjava 入门篇

    什么是 rxJava? RxJava is a Java VM implementation of Reactive Extensions: a library for composing async ...

  5. 现代C++学习笔记之二入门篇2,数据转换

    static_cast:    这种强制转换只会在编译时检查. 如果编译器检测到您尝试强制转换完全不兼容的类型,则static_cast会返回错误. 您还可以使用它在基类指针和派生类指针之间强制转换, ...

  6. 现代C++学习笔记之二入门篇1

    现代 C++ 强调: 基于堆栈的范围,而非堆或静态全局范围. 自动类型推理,而非显式类型名称. 智能指针而不是原始指针. std::string 和 std::wstring 类型(请参见 <s ...

  7. Android数据绑定技术一,企业级开发

    PS:数据绑定,顾名思义是数据与一些控件或者用户账号等绑定,这样用的好处是便于管理.代码清晰,量少. 首先要了解什么是数据绑定? 为什么要用数据绑定? 怎么用数据绑定? 语法的使用 简单例子,数据绑定 ...

  8. 【Android开发日记】之入门篇(十二)——Android组件间的数据传输

    组件我们有了,那么我们缺少一个组件之间传递信息的渠道.利用Intent做载体,这是一个王道的做法.还有呢,可以利用文件系统来做数据共享.也可以使用Application设置全局数据,利用组件来进行控制 ...

  9. 【Android开发日记】之入门篇(三)——Android目录结构

    本来的话,这一章想要介绍的是Android的系统架构,毕竟有了这些知识的储备,再去看实际的项目时才会更清楚地理解为什么要这样设计,同时在开发中遇到难题,也可以凭借着对Android的了解,尽快找出哪些 ...

随机推荐

  1. 通过python全局设置id——自动化测试元素定位

    背景: 在自动化化测试过程中,不方便准确获取页面的元素,或者在重构过程中方法修改造成元素层级改变,因此通过设置id准备定位. 一.python准备工作: 功能:用自动化的方式进行批量处理. 比如,你想 ...

  2. Computer Vision_33_SIFT:A novel coarse-to-fine scheme for automatic image registration based on SIFT and mutual information——2014

    此部分是计算机视觉部分,主要侧重在底层特征提取,视频分析,跟踪,目标检测和识别方面等方面.对于自己不太熟悉的领域比如摄像机标定和立体视觉,仅仅列出上google上引用次数比较多的文献.有一些刚刚出版的 ...

  3. SQL SERVER-端口Port

    Quick cheat sheet for port numbers used by SQL Server services or services that SQL Server may depen ...

  4. Win 2008 R2——由于管理员设置的策略,该磁盘处于脱机状态

    操作系统:Windows 2008R2 现象描述: 1.原系统为Windows 2012挂载了2T的存储,因业务要求重新安装为Windows 2008R2,并没有在磁盘存储空间上重新做映射. 2.系统 ...

  5. 使用Wireshark对手机抓包设置说明

    一.原因 1.手机目前没有类似的抓包工具可以直接对手机进行抓包 2.一般数据交换的路线是:手机——>运营商——>服务器,可以在手机和运营商中间加一道网卡变成:手机——>PC网卡——& ...

  6. JS多线程之Web Worker

    什么是Web Worker web worker 是运行在后台的 JavaScript,不会影响页面的性能. 当在 HTML 页面中执行脚本时,页面的状态是不可响应的,直到脚本已完成. web wor ...

  7. Django连接MySQL数据库配置

    1.自己手动创建数据库 create database 数据库名; # 如: create database bms character set utf8; # 授权访问: grant all pri ...

  8. rsync详细解读

    本文通过示例详细分析rsync算法原理和rsync的工作流程,是对rsync官方技术报告和官方推荐文章的解释.本文不会介绍如何使用rsync命令(见rsync基本用法),而是详细解释它如何实现高效的增 ...

  9. SCPI 语言简介

    电子负载中需要用到,所以记录下.来源是德科技 SCPI(可编程仪器的标准命令)是一种基于 ASCII 的仪器编程语言,供测试和测量仪器使用. SCPI 命令采用分层结构,也称为树系统. 相关命令归组于 ...

  10. chrome开启headless模式以及代理

    google-chrome-stable --disable-gpu --remote-debugging-port=9222 --headless -remote-debugging-address ...