文档章节

RxBinding响应控件事件

开源中国驻成都办事处
 开源中国驻成都办事处
发布于 2016/07/21 14:01
字数 794
阅读 239
收藏 0

前面提到了两个RxBinding库。后者已经讲过是实现Model和View之间的单向绑定。前者是今天讨论的内容,JakeWharton/RxBinding能够帮助我们简化对控件操作的响应处理。不仅仅包括控件本身已经提供的一些Listener,还包括对控件属性变化的响应。

  • https://github.com/JakeWharton/RxBinding
  • https://github.com/ogaclejapan/RxBinding

JakeWharton/RxBinding是对Android控件提供响应式支持的,所以它分为了几个不同的库。com.jakewharton.rxbinding:rxbinding提供对标准的Android控件支持;com.jakewharton.rxbinding:rxbinding-support-v4提供对Support V4库的支持;com.jakewharton.rxbinding:rxbinding-appcompat-v7提供对V7兼容包的支持;com.jakewharton.rxbinding:rxbinding-design提供对Material Design库的支持;com.jakewharton.rxbinding:rxbinding-recyclerview-v7提供对RecycleView的支持。另外每个库还有对应的kotlin扩展支持库,名字以“-kotlin”结尾。

为了分析JakeWharton/RxBinding实现的原理,我们从一个简单的例子开始:

etUIBinding = (EditText) this.findViewById(R.id.et_ui_binding);
tvUIBinding = (TextView) this.findViewById(R.id.tv_ui_binding);
RxTextView.textChanges(etUIBinding).subscribe(new Action1<CharSequence>() {
	@Override
	public void call(CharSequence charSequence) {
		tvUIBinding.setText(charSequence);
	}
});

如果是Java8,最后一句可以使用lamba表达式:用tvUIBinding.setText替换掉冗长的匿名对象Action1。

可以猜测,RxTextView.textChanges应该返回了一个Observable。实际上它的类型是Observable<CharSequence>,是调用Observable.create(new TextViewTextOnSubscribe(view))创建的。TextViewTextOnSubscribe继承自Observable.OnSubscribe<CharSequence>,指定了观察者Observer注册时Observable需要执行的操作。

final class TextViewTextOnSubscribe implements Observable.OnSubscribe<CharSequence> {
  // EditText继承自TextView,使用TextView还可以让TextView的值的变化被观测到
  final TextView view;

  TextViewTextOnSubscribe(TextView view) {
    this.view = view;
  }
  // Observer调用subscribe时执行的动作
  @Override public void call(final Subscriber<? super CharSequence> subscriber) {
    checkUiThread();
    // 创建一个检测TextView文本变化的watcher
    final TextWatcher watcher = new TextWatcher() {
      @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {
      }

      @Override public void onTextChanged(CharSequence s, int start, int before, int count) {
        if (!subscriber.isUnsubscribed()) {
          subscriber.onNext(s);
        }
      }

      @Override public void afterTextChanged(Editable s) {
      }
    };
	// 注册watcher作为TextView文本变化时的Listener
    view.addTextChangedListener(watcher);
	// 每个Subscriber内部都有一个SubscriptionList,其持有LinkedList<Subscription>,
	// 可以定义一系列Subscriber unsubscribe时候需要执行的动作。
	// 这里用于将watcher从TextView移除
    subscriber.add(new MainThreadSubscription() {
      @Override protected void onUnsubscribe() {
        view.removeTextChangedListener(watcher);
      }
    });

    // 发送一个初始值,其值是当前TextView的值
    subscriber.onNext(view.getText());
  }
}

得到一个Observable之后,我们就可以调用Observable.subscribe来绑定一个Observer。示例中subscribe的是一个Action1对象,它只对onNext进行相应。示例的Action1对象的功能是更新TextView的显示。

public final Subscription subscribe(final Action1<? super T> onNext) {
	if (onNext == null) {
		throw new IllegalArgumentException("onNext can not be null");
	}
	return subscribe(new Subscriber<T>() {
		@Override
		public final void onCompleted() {
			// do nothing
		}
		@Override
		public final void onError(Throwable e) {
			throw new OnErrorNotImplementedException(e);
		}
		@Override
		public final void onNext(T args) {
			onNext.call(args);
		}

	});
}

现在来总结下示例代码执行的流程:

  1. 创建了一个Action1作为Observer,来更新TextView的显示
  2. 创建一个Observable,处理onSubscribe的任务交给TextViewTextOnSubscribe
  3. 调用Observable.subscribe来建立Observer和Observable的联系
  4. 调用TextViewTextOnSubscribe.call
  5. 创建一个TextWatcher来监听EditView的文本变化
  6. EditView的文本变化后,TextWatcher的onTextChanged被调用
  7. 向Observer发送当前的文本,调用Observer提供的onNext,即Action1.call
  8. Action1.callTextView的显示

其他控件的支持应该是类似的。

要使用JakeWharton/RxBinding的话,要熟悉它的命名方式,这样就能很容易找到自己想要的API。

© 著作权归作者所有

共有 人打赏支持
开源中国驻成都办事处
粉丝 84
博文 287
码字总数 335913
作品 0
成都
程序员
RxBinding单向数据绑定

如果你去Github上搜索RxBinding的话,会有两个靠前的结果: https://github.com/JakeWharton/RxBinding https://github.com/ogaclejapan/RxBinding 前者完成的功能是对控件的操作进行响应式扩...

开源中国驻成都办事处
2016/07/18
601
0
RxJava与RxAndroid的学习之路

RxJava 和 RxAndroid 四(RxBinding的使用) 对Rxjava不熟悉的同学可以先看我之前写的几篇文章 RxJava 和 RxAndroid 一 (基础) RxJava 和 RxAndroid 二(操作符的使用) RxJava 和 RxAndroi...

guozhendan
06/26
0
0
初涉Rx套餐 之RxBinding(让你的事件流程更清晰)

转载请注明出处:王亟亟的大牛之路 最近下班回家都在WOW,周末就爆肝,感觉人都要GO DIE了,昨天下午看了看RxBinding相关的功能感觉还是蛮强大的,所提供的API也是相当丰富(基本Rx套餐都是互...

ddwhan0123
2016/09/07
0
0
RxBinding使用和源码解析

RxJava想必做Android都用过,即使没用过肯定也听过。RxBinding这个库是 JakeWharton的大作,可以响应式的方式来处理UI的响应问题,比如按钮的点击事件,ListView的点击事件,EditText的文本变...

juexingzhe
2017/12/21
0
0
RxBinding,Rxjava,RxPermissions的简单的总结

RxPermissions总结 Rxjava中知识点总结 Subscriber和Observer接口的区别: 在RxJava2版本中2.1.11中没有区别 <--特别注意:2种方法的区别,即Subscriber 抽象类与Observer 接口的区别 --> 1、...

OneXzgj
05/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

MySQL 8 在 Windows 下安装及使用

MySQL 8 带来了全新的体验,比如支持 NoSQL、JSON 等,拥有比 MySQL 5.7 两倍以上的性能提升。本文讲解如何在 Windows 下安装 MySQL 8,以及基本的 MySQL 用法。 下载 下载地址 https://dev....

waylau
35分钟前
0
0
微信第三方平台 access_token is invalid or not latest

微信第三方开发平台code换session_key说的特别容易,但是我一使用就带来无穷无尽的烦恼,搞了一整天也无济于事. 现在记录一下解决问题的过程,方便后来人参考. 我遇到的这个问题搜索了整个网络也...

自由的开源
今天
0
0
openJDK之sun.misc.Unsafe类CAS底层实现

注:这篇文章参考了https://www.cnblogs.com/snowater/p/8303698.html 1.sun.misc.Unsafe中CAS方法 在sun.misc.Unsafe中CAS方法如下: compareAndSwapObject(java.lang.Object arg0, long a......

汉斯-冯-拉特
今天
1
0
设计模式之五 责任链模式(Chain of Responsibility)

一. 场景 相信我们都有过这样的经历; 我们去职能部门办理一个事情,先去了A部门,到了地方被告知这件事情由B部门处理; 当我们到了B部门的时候,又被告知这件事情已经移交给了C部门处理; ...

JackieRiver
今天
1
0
Android中的设计模式之命令模式

参考 《设计模式:可复用面向对象软件的基础 》5.2 Command 命令 对象行为型模式 《Android源码设计模式解析与实战》第11章 让程序畅通执行--命令模式 意图 将一个请求封装为一个对象,从而使...

newtrek
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部