In the previous tutorials, we discussed RxJava and some of its operators. Today we will discuss the RxBinding library in our Android Application.

在之前的教程中,我们讨论了RxJava及其一些运算符 。 今天,我们将在Android应用程序中讨论RxBinding库。

Rx绑定 (RxBinding)

We know that RxJava is a reactive event-based programming paradigm.
RxBinding is a set of support libraries to make the implementation of user interaction with the UI elements in Android easier.

我们知道RxJava是一种基于事件的React式编程范例。
RxBinding是一组支持库,可简化与Android中的UI元素的用户交互的实现。

To use RxBinding in your application you must include:

要在您的应用程序中使用RxBinding,您必须包括:

implementation  'com.jakewharton.rxbinding2:rxbinding:2.0.0'

Using this along with the RxJava dependency:

与RxJava依赖项一起使用:

implementation  'io.reactivex.rxjava2:rxjava:2.1.9'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'

To use RxBinding with Appcompat and other submodules we simply need to import their respective rxbinding libraries:

要将RxBinding与Appcompat和其他子模块一起使用,我们只需要导入它们各自的rxbinding库:

  • implementation com.jakewharton.rxbinding2:rxbinding-recyclerview-v7:2.0.0'implementation com.jakewharton.rxbinding2:rxbinding-recyclerview-v7:2.0.0'
  • implementation 'com.jakewharton.rxbinding2:rxbinding-support-v4:2.0.0'implementation 'com.jakewharton.rxbinding2:rxbinding-support-v4:2.0.0'
  • implementation 'com.jakewharton.rxbinding2:rxbinding-appcompat-v7:2.0.0'implementation 'com.jakewharton.rxbinding2:rxbinding-appcompat-v7:2.0.0'
  • implementation 'com.jakewharton.rxbinding2:rxbinding-design:2.0.0'implementation 'com.jakewharton.rxbinding2:rxbinding-design:2.0.0'
  • implementation 'com.jakewharton.rxbinding2:rxbinding-recyclerview-v7:2.0.0'implementation 'com.jakewharton.rxbinding2:rxbinding-recyclerview-v7:2.0.0'
  • compile 'com.jakewharton.rxbinding2:rxbinding-leanback-v17:2.0.0'compile 'com.jakewharton.rxbinding2:rxbinding-leanback-v17:2.0.0'

we can use RxBinding features in our application.

我们可以在应用程序中使用RxBinding功能。

RxView.click() (RxView.click())

Typically, to set click listener events on a Button, the following is the piece of code that we write:

通常,要在Button上设置点击侦听器事件,以下是我们编写的代码段:

Button b = (Button)findViewById(R.id.button);
b.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(getApplicationContext(),"Button clicked",Toast.LENGTH_SHORT).show();}});

Now with RxBinding we can do:

现在,使用RxBinding,我们可以执行以下操作:

Disposable d = RxView.clicks(button).subscribe(new Consumer<Object>() {@Overridepublic void accept(Object o) {Toast.makeText(getApplicationContext(),"Button clicked",Toast.LENGTH_SHORT).show();}});

Inside RxView.clicks we pass the View instance which is to be clicked.

RxView.clicks内部,我们传递了要单击的View实例。

If you are new to RxJava2, Disposable is equivalent to Subscription.
For more information on changes in RxJava2 refer here.

如果您不熟悉RxJava2,则Disposable等同于Subscription。
有关RxJava2中更改的更多信息,请参见此处 。

On the Disposable instance we can unsubscribe from the event by calling d.dispose();.
The Disposable instance holds a reference to the view. So if this code is defined outside the context of the Activity, you must unsubscribe from the event to prevent memory leaks.

在Disposable实例上,我们可以通过调用d.dispose();取消订阅该事件d.dispose();
Disposable实例包含对该视图的引用。 因此,如果此代码是在Activity上下文之外定义的,则必须取消订阅该事件,以防止内存泄漏。

RxView.click() returns an Observable. So we can add RxJava operators to perform transformations and chain implementations on it.

RxView.click()返回一个Observable。 因此,我们可以添加RxJava运算符以在其上执行转换和链式实现。

EditText TextChanges (EditText TextChanges)

Typically to add text change listeners on an EditText we need to implement the TextWatcher methods:

通常,要在EditText上添加文本更改侦听器,我们需要实现TextWatcher方法:

EditText editText = findViewById(R.id.editText);
editText.addTextChangedListener(new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence s, int start, int count, int after) {}@Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {}@Overridepublic void afterTextChanged(Editable s) {}
});

Using RxBinding we can do:

使用RxBinding,我们可以执行以下操作:

Disposable d2 = RxTextView.textChanges(editText).subscribe(new Consumer<CharSequence>() {@Overridepublic void accept(CharSequence charSequence) throws Exception {//Add your logic to work on the Charsequence}});

We pass the EditText inside RxTextView.textChanges.

我们在RxTextView.textChanges内部传递EditText。

Now let’s see how RxJava operators and transformations give us leverage.

现在,让我们看看RxJava运算符和转换如何给我们带来影响。

使用地图运算符 (Using Map operator)

Using map operator we can change the data that is being sent.
For example, in the EditText we can change the CharSequence to a String

使用地图运算符,我们可以更改正在发送的数据。
例如,在EditText中,我们可以将CharSequence更改为String

Disposable d2 = RxTextView.textChanges(editText).map(charSequence -> charSequence.toString()).subscribe(new Consumer<CharSequence>() {@Overridepublic void accept(String string) throws Exception {//Add your logic to work on the Charsequence}});

使用反跳运算符 (Using debounce operator)

Using a debounce operator we can delay the event action.

使用反跳运算符,我们可以延迟事件动作。

For example, on the Button click, we can set a debounce of 2 seconds. This will run the operation after 2 seconds:

例如,在“按钮”上单击,我们可以将去抖设置为2秒。 2秒后将运行该操作:

RxView.clicks(button).debounce(2, TimeUnit.SECONDS).observeOn(AndroidSchedulers.mainThread()).map(o -> button.getText().toString()).subscribe(new Consumer<String>() {@Overridepublic void accept(String o) throws Exception {Toast.makeText(getApplicationContext(),o + "was clicked",Toast.LENGTH_SHORT).show();}});

A debounce operation doesn’t run on the UI thread. It runs on the computational thread.
Hence you must call the main thread in the observeOn method after that as done above.

反跳操作不在UI线程上运行。 它在计算线程上运行。
因此,如上所述,您必须在此之后在observeOn方法中调用主线程。

A debounce operator is commonly used in EditText, especially in a SearchView to let the user stop typing for a few seconds before running the action/requests.

反跳运算符通常在EditText中使用,尤其是在SearchView中,可以使用户在运行操作/请求之前停止键入几秒钟。

使用节流阀 (Using throttleFirst)

Unlike debounce which delays the action, throttleFirst operator is used in preventing repeated actions within a certain time interval.
ThrottleFirst is useful when it comes to preventing double actions when a Button is repeatedly clicked.

与防抖会延迟动作不同, throttleFirst运算符用于防止在特定时间间隔内重复动作。
ThrottleFirst对于防止重复单击按钮时的双重操作很有用。

RxView.clicks(button).throttleFirst(2, TimeUnit.SECONDS).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Object>() {@Overridepublic void accept(Object o) {Toast.makeText(getApplicationContext(), "Avoid multiple clicks using throttleFirst", Toast.LENGTH_SHORT).show();}});

In the above code, the Button won’t show a Toast again until after 2 seconds.

在上面的代码中,Button直到2秒后才会再次显示Toast。

Merging Multiple Button click actions

合并多个按钮单击动作

We can merge RxView.click() Observables in the following way:

我们可以通过以下方式合并RxView.click() Observables:

Button button1 = findViewById(R.id.button1);
Button button2 = findViewById(R.id.button2);
Observable<Object> observable1 = RxView.clicks(button1);
Observable<Object> observable1 = RxView.clicks(button2);Observable.merge(observable1, observable2).subscribe(new Consumer<Object>() {@Overridepublic void accept(Object o) {//This common logic would be triggered when either of them are clicked}});

Multiple Click Listeners on a Button

一个按钮上的多个单击侦听器

CompositeDisposable compositeDisposable = new CompositeDisposable();Observable<Button> clickObservable = RxView.clicks(button).map(o -> button).share();Disposable buttonShowToast =clickObservable.subscribe(new Consumer<Button>() {@Overridepublic void accept(Button o) throws Exception {Toast.makeText(getApplicationContext(), "Show toast", Toast.LENGTH_SHORT).show();}});compositeDisposable.add(buttonShowToast);Disposable changeButtonText =clickObservable.subscribe(new Consumer<Button>() {@Overridepublic void accept(Button o) throws Exception {o.setText("New text");}});compositeDisposable.add(changeButtonText);

Using the share operator on the RxView.click() observable, both the Disposables created below are run when the button is clicked.

使用可观察到的RxView.click()上的share运算符,单击该按钮时,将同时运行下面创建的两个Disposable。

Let’s merge the above concepts in our Android Application with a few more operators:

让我们在Android应用程序中将以上概念与更多运算符合并:

项目结构 (Project Structure)

码 (Code)

activity_main.xml

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"xmlns:app="https://schemas.android.com/apk/res-auto"xmlns:tools="https://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><EditTextandroid:id="@+id/editText"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="Enter here!"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintVertical_bias="0.35000002" /><TextViewandroid:id="@+id/txtBelowEditText"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginEnd="8dp"android:layout_marginLeft="8dp"android:layout_marginRight="8dp"android:layout_marginStart="8dp"android:layout_marginTop="16dp"android:text="TextView"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/editText" /><Buttonandroid:id="@+id/button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Button"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.5"app:layout_constraintStart_toEndOf="@+id/button2"app:layout_constraintBaseline_toBaselineOf="@+id/button2"/><Buttonandroid:id="@+id/button2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="16dp"android:text="Button2"app:layout_constraintEnd_toStartOf="@+id/button"app:layout_constraintHorizontal_bias="0.5"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><TextViewandroid:id="@+id/txtBelowButton"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="16dp"android:text="TextView"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/button2" /><android.support.design.widget.FloatingActionButtonandroid:id="@+id/fab"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginBottom="24dp"android:layout_marginTop="8dp"android:src="@android:drawable/ic_input_add"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"/><Buttonandroid:id="@+id/button3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Simulateneous Actions"app:layout_constraintBottom_toTopOf="@+id/fab"android:layout_margin="8dp"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"/></android.support.constraint.ConstraintLayout>

MainActivity.java

MainActivity.java

package com.journaldev.androidrxbinding;import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;import com.jakewharton.rxbinding2.view.RxView;
import com.jakewharton.rxbinding2.widget.RxTextView;import java.util.concurrent.TimeUnit;import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;public class MainActivity extends AppCompatActivity {Button button, button2, button3;FloatingActionButton fab;TextView txtBelowEditText, txtBelowButton;EditText editText;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);button = findViewById(R.id.button);button2 = findViewById(R.id.button2);button3 = findViewById(R.id.button3);fab = findViewById(R.id.fab);txtBelowEditText = findViewById(R.id.txtBelowEditText);txtBelowButton = findViewById(R.id.txtBelowButton);editText = findViewById(R.id.editText);Observable<Object> observable1 = RxView.clicks(button2).map(o -> button2);Observable<Object> observable2 = RxView.clicks(fab).map(o -> fab);Disposable d1 = Observable.merge(observable1, observable2).throttleFirst(2, TimeUnit.SECONDS).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Object>() {@Overridepublic void accept(Object o) {Toast.makeText(getApplicationContext(), "Avoid multiple clicks using throttleFirst", Toast.LENGTH_SHORT).show();if (o instanceof Button) {txtBelowButton.setText(((Button) o).getText().toString() + " clicked");} else if (o instanceof FloatingActionButton) {txtBelowButton.setText("Fab clicked");}}});Disposable d = RxView.clicks(button).debounce(5, TimeUnit.SECONDS).observeOn(AndroidSchedulers.mainThread()).map(o -> button.getText().toString()).subscribe(new Consumer<String>() {@Overridepublic void accept(String o) throws Exception {txtBelowButton.setText(o + " was clicked");}});Disposable d2 = RxTextView.textChanges(editText).filter(s -> s.toString().length() > 6).debounce(2, TimeUnit.SECONDS).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<CharSequence>() {@Overridepublic void accept(CharSequence charSequence) throws Exception {txtBelowEditText.setText(charSequence);}});CompositeDisposable compositeDisposable = new CompositeDisposable();Observable<Button> clickObservable = RxView.clicks(button3).map(o -> button3).share();Disposable buttonShowToast =clickObservable.subscribe(new Consumer<Button>() {@Overridepublic void accept(Button o) throws Exception {Toast.makeText(getApplicationContext(), "Show toast", Toast.LENGTH_SHORT).show();}});compositeDisposable.add(buttonShowToast);Disposable changeButtonText =clickObservable.subscribe(new Consumer<Button>() {@Overridepublic void accept(Button o) throws Exception {o.setText("New text");}});compositeDisposable.add(changeButtonText);}}

In the EditText, we’ve set a filter operator which doesn’t set the input text onto the TextView until the length crosses a threshold.

在EditText中,我们设置了一个filter运算符,直到长度超过阈值时才将输入文本设置到TextView上。

To clear all the Disposables, instead of calling disposable() on each of them separately, we can do the following as well:

要清除所有Disposable,而不是分别对每个Disposable()进行调用,我们还可以执行以下操作:

CompositeDisposable clearAllDisposables = new CompositeDisposable();clearAllDisposables.add(d1);clearAllDisposables.add(d2);clearAllDisposables.add(d);clearAllDisposables.clear();

The output of the application in action is given below:

实际应用程序的输出如下:

Notice how many times the FloatingActionButton was clicked. But the Toast was displayed just once.

注意单击FloatingActionButton的次数。 但是吐司只被展示了一次。

This brings an end to this tutorial. You can download the project from the link below:

本教程到此结束。 您可以从下面的链接下载项目:

AndroidRxBindingAndroidRxBinding
AndroidRxBindingAndroidRxBinding

翻译自: https://www.journaldev.com/22527/android-rxbinding

Android RxBinding相关推荐

  1. android novate乱码,Android RxJava+Retrofit2+RxBinding

    Android RxJava+Retrofit2+RxBinding 本文原创,转载请注明出处.欢迎关注我的 简书. 安利一波我写的开发框架:MyScFrame喜欢的话就给个Star 前言: 之前写了 ...

  2. Android专题-常用第三方框架

    Android专题-常用第三方框架 HTTP网络请求 带*号的是个人推荐比较好用的 HTTP网络请求 okhttp * :https://github.com/square/okhttp retrof ...

  3. android 多个绑定事件,Android RxJava 实际应用讲解:联合判断多个事件

    前言 Rxjava,由于其基于事件流的链式调用.逻辑简洁 & 使用简单的特点,深受各大 Android开发者的欢迎. Github截图 RxJava如此受欢迎的原因,在于其提供了丰富 & ...

  4. android好用的第三方库2018使用总结

    不知不觉2018年已经过了大半,来总结一下今年用到的一些好用的框架和第三方库,包括App架构.异步通信库.注入注解框架.网络请求库.图片加载库.动画库.数据库.音频视频库.平台分享库.蓝牙库.权限请求 ...

  5. Android -- 带你从源码角度领悟Dagger2入门到放弃(三)

    1, 前面两篇文章我们知道了怎么使用常用的四种标签,现在我们结合我们自己的项目中去简单的使用 在我们搭建项目的时候,一般会创建自己的Application,在里面进行一些初始化如一些第三方的Green ...

  6. 15个Android通用流行框架大全

    1. 缓存 DiskLruCache    Java实现基于LRU的磁盘缓存 2.图片加载 Android Universal Image Loader  一个强大的加载,缓存,展示图片的库 Pica ...

  7. 15类Android通用流行框架

    15类Android通用流行框架 Android流行框架 缓存 DiskLruCache Java实现基于LRU的磁盘缓存 图片加载 Android Universal Image Loader 一个 ...

  8. Android 通用流行框架大全

     尊重原创 1.这个也是框架总合 2.百大框架等你来拿 3.Studio的插件 1. 缓存 名称 描述 DiskLruCache Java实现基于LRU的磁盘缓存 2.图片加载 名称 描述 Andro ...

  9. RxJava 在Android中的应用(一)

    RxJava 在Android中的应用 RxJava 是什么, 能解决什么问题 对比其他技术理解为什么要选择RxJava RxJava的相关API RxJava在Android中的典型使用场景 RxJ ...

最新文章

  1. 客户端如何连接 DataSnap Server 调用服务的方法
  2. mysql 唯一性约束报错_怪异的MySQL Online DDL报错Duplicate entry
  3. ios开发Base64编码以及加密相关学习
  4. DOS 批处理命令学习1
  5. DNS服务器分离解析 RAID阵列 进程管理 日志管理 systemd作用
  6. 使用Asynchronous RFC call 拆分time consuming task
  7. IdentityServer4系列 | 授权码模式
  8. python求散点曲线下方面积
  9. 【java】JVM Attach机制实现与jstack使用(jvm参数DisableAttachMechanism)
  10. android动态service,Android基础回顾之Service
  11. mysql deadlock 记录_MySQL DeadLock故障排查全过程记录
  12. python卸载干净_Python卸载不干净?Mac完全卸载python方法
  13. 宏转录组方法_中山大学医学院施莽教授学术讲座:宏转录组方法在病原生物学领域的应用...
  14. 一年级古诗《画》知识点心田花开汇总
  15. java 工资如何_Java编写员工薪资表
  16. Buffer() is deprecated due to security and usability issues.webpack 报错
  17. 银行笔试用计算机,2018银行招聘笔试:如何备考银行计算机
  18. 买房子了~128.41平方哦`
  19. 在普通maven项目应用中使用MQ
  20. 华视cvr-100UC 二代身份证读卡通用函数

热门文章

  1. Android知识散点
  2. Android adb不是内部或外部命令 问题解决
  3. 基于Volley框架的图片渐变显示alpha动画
  4. 关于div布局中float的使用
  5. Delphi ArcEngine 创建比例尺
  6. [转载] Java 中的binarySearch方法
  7. [转载] python 字符串切片_Python字符串
  8. [转载] Java异常处理中Try-Catch-Finally中常见的笔试题
  9. shell学习笔记(五)
  10. 洛谷 2633 BZOJ 2588 Spoj 10628. Count on a tree