RxBinding具体使用

学了RxJava的响应式编程之后,感觉RxBinding也有必要记录一下使用,在项目中使用还是比较多的,只介绍一下使用。
RxBinding

1.依赖

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

依赖RxBinding就不需要再依赖RxJava了,内部已经包含了

使用RxJava实例化的Disposable需在不用时及时销毁。

public abstract class BaseActivity extends AppCompatActivity {
public CompositeDisposable mCompositeDisposable;
private Unbinder mUnbinder;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(getLayoutId());
    mUnbinder = ButterKnife.bind(this);
    mCompositeDisposable = new CompositeDisposable();
    onViewCreated(savedInstanceState);
}

/**
 * 添加订阅
 */
public void addDisposable(Disposable mDisposable) {
    if (mCompositeDisposable == null) {
        mCompositeDisposable = new CompositeDisposable();
    }
    mCompositeDisposable.add(mDisposable);
}

/**
 * 取消所有订阅
 */
public void clearDisposable() {
    if (mCompositeDisposable != null) {
        mCompositeDisposable.clear();
    }
}

@Override
protected void onDestroy() {
    super.onDestroy();
    clearDisposable();
    mUnbinder.unbind();
}

protected abstract int getLayoutId();

protected abstract void onViewCreated(Bundle savedInstanceState);
 }
2.RxView

使用RxBinding可做到点击防抖的效果,调用这个方法便可防止短时间内对View的重复点击,本例中设置的防抖时间为2s。

       RxView.clicks(btnLogin)
            .throttleFirst(2, TimeUnit.SECONDS)
            .subscribe(new Consumer<Object>() {
                @Override
                public void accept(Object o) throws Exception {
                    Toast.makeText(MainActivity.this, "11111111111", Toast.LENGTH_LONG).show();
                }
            });
throttleFirst(long windowDuration, TimeUnit unit),设置一定时间内只响应首次(throttleFirst)或者末次(throttleLast)的点击事件。windowDuration为防抖时间,unit为时间单位。

长按监听

     RxView.longClicks(btnLogin)
            .subscribe(new Consumer<Object>() {
                @Override
                public void accept(Object o) throws Exception {
                    Toast.makeText(MainActivity.this, "2222222222", Toast.LENGTH_LONG).show();
                }
            });

绘制监听

   //当btnLogin绘制时触发
  RxView.draws(btnLogin)
            .subscribe(new Consumer<Object>() {
                @Override
                public void accept(Object o) throws Exception {

                }
            });

拖拽监听

    //拖拽监听
    RxView.drags(btnLogin)
            .subscribe(new Consumer<DragEvent>() {
                @Override
                public void accept(DragEvent dragEvent) throws Exception {
                    Toast.makeText(MainActivity.this, "被拖拽了", Toast.LENGTH_LONG).show();
                }
            });

滑动时触发

    //滑动时触发
    RxView.scrollChangeEvents(btnLogin)
            .subscribe(new Consumer<ViewScrollChangeEvent>() {
                @Override
                public void accept(ViewScrollChangeEvent viewScrollChangeEvent) throws Exception {

                }
            });

EditText输入监听

  // addTextChangedListener
    RxTextView.textChanges(userNameEt).subscribe(new Consumer<CharSequence>() {
        @Override
        public void accept(CharSequence text) throws Exception {
            Toast.makeText(MainActivity.this, "2222222222", Toast.LENGTH_LONG).show();
            clearContent.setVisibility(TextUtils.isEmpty(text) ? View.INVISIBLE : View.VISIBLE);
        }
    });

合并监听

   Observable<CharSequence> userNameObservable = RxTextView.textChanges(userNameEt);
    Observable<CharSequence> userPwdObservable = RxTextView.textChanges(userPasswordEt);
    // 相当于合并
    Observable.combineLatest(userNameObservable, userPwdObservable,
            new BiFunction<CharSequence, CharSequence, Object>() {
                @Override
                public Object apply(CharSequence userName, CharSequence userPwd) throws Exception {
                    Toast.makeText(MainActivity.this, "33333", Toast.LENGTH_LONG).show();
                    // 设置按钮是否可用(或者改变背景颜色)
                    clearContent.setEnabled(!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPwd));
                    return null;
                }
            });

控件操作时间间隔

   // 控件操作时间间隔
    RxTextView.textChanges(mUserNameEt).debounce(1200, TimeUnit.MILLISECONDS)
            .subscribe(new Consumer<CharSequence>() {
                @Override
                public void accept(CharSequence charSequence) throws Exception {
                    log("debounce");
                }
            });

接口轮询,轮询操作

 // 接口轮询,轮询操作
    Observable.interval(2, 2, TimeUnit.SECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) throws Exception {
            log("interval");
        }
    });

延时操作

    // 延时操作
    Observable.timer(2, TimeUnit.SECONDS)
            .subscribe(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) throws Exception {
                    log("timer");
                }
            });

其他

        RxView.visibility(btnClick).accept(true);
        RxView.clickable(btnClick).accept(true);
        RxView.enabled(btnClick).accept(true);

RxTextView

textChanges

RxTextView.textChanges(TextView view),内部封装了TextWatcher文本改变监听。

       RxTextView.textChanges(etRxTextView)
              .subscribe(new Consumer<CharSequence>() {
                   @Override
                public void accept(CharSequence charSequence) throws Exception {
                  Log.e("rx_binding_test", "textChanges:文本改变了:" + charSequence.toString());
             }
           });

textChangeEvents

RxTextView.textChangeEvents(TextView view),内部同样封装了TextWatcher文本改变监听。不同的是其返回数据的类型为TextViewTextChangeEvent,内部包含详细的文本改变数据。

    RxTextView.textChangeEvents(etRxTextView)
    .subscribe(textViewTextChangeEvent -> {
        Log.e("rx_binding_test", "textChanges:文本改变了:" + "before:" + textViewTextChangeEvent.before() + 
            ",start:" + textViewTextChangeEvent.start() + ",text:" + textViewTextChangeEvent.text() + 
            ",count:" + textViewTextChangeEvent.count());
    });

editorActions

RxTextView.editorActions(TextView view),内部封装了OnEditorActionListener软键盘回车点击监听。

     RxTextView.editorActions(etRxTextView)
      .subscribe(integer -> {
        Log.e("rx_binding_test", "editorActions:输入完毕,点击回车:");
    });

editorActionEvents

RxTextView.editorActionEvents(TextView view),内部同样封装了OnEditorActionListener软键盘回车点击监听。不同的是它的返回类型为TextViewEditorActionEvent,包含actionId,keyEvent等信息

     RxTextView.editorActionEvents(etRxTextView)
       .subscribe(textViewEditorActionEvent -> {
        KeyEvent keyEvent = textViewEditorActionEvent.keyEvent();
        //判断up状态
        if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_ENTER && keyEvent.getAction() == KeyEvent.ACTION_UP) {
            Log.e("rx_binding_test", "editorActionEvents:输入完毕,点击回车:" + textViewEditorActionEvent.keyEvent());
        }
    });

RxTextView中还封装了一些常用的例如setText()、setHint()、setTextColor()等TextView的操作。使用起来也很简单,如下:

       RxTextView.editorActions(etRxTextView)
     .subscribe(integer -> {
        RxTextView.text(etRxTextView).accept("呵呵");
        RxTextView.hint(etRxTextView).accept("请输入姓名");
        RxTextView.color(etRxTextView).accept(Color.parseColor("#00ff00"));
     });

实际场景

在实际项目开发中经常会遇到搜索文本框需根据用户实时输入的文本进行检索,或去数据库查询,或去服务器请求检索。如果文本每改变一次都去检索的话会导致重复大量查数据库或请求服务器,很影响内存。来看下使用RxBinding如何解决这个问题。

  addDisposable(RxTextView.textChanges(etRxTextView)
    //限流时间500ms
    .debounce(500, TimeUnit.MILLISECONDS)
    .observeOn(AndroidSchedulers.mainThread())
    //CharSequence转换为String
    .map(CharSequence::toString)
    .subscribe(s -> {
        //这里可以查询数据库或请求服务器查询
        Log.e("rx_binding_test", "textChanges:文本改变了:" + s);
    }));

正是由于RxBinding使用的是RxJava形式,所以RxJava中的操作符我们都可以使用。利用debounce操作符进行限流,就能避免因为用户输入速度过快导致多次请求服务器了。还可以利用map操作符将CharSequence转换为String再返回。

RxCompoundButton

checkedChanges选中状态改变事件

RxCompoundButton.checkedChanges(CompoundButton view),内部封装了OnCheckedChangeListener选中状态改变监听。

    //默认注册按钮不可点击
   btnLogin.setEnabled(false);
   RxCompoundButton.checkedChanges(cbContract)
    .subscribe(aBoolean -> {
        RxView.enabled(btnLogin).accept(aBoolean);
        btnLogin.setBackgroundResource(aBoolean ? R.color.colorPrimary : R.color.colorGray);
        RxTextView.color(btnLogin).accept(aBoolean ? Color.parseColor("#ffffff") :
                Color.parseColor("#000000"));
    });
 RxView.clicks(btnLogin)
    //防抖2s
    .throttleFirst(2, TimeUnit.SECONDS)
    .subscribe(o -> Toast.makeText(RxCompoundButtonActivity.this, "注册成功",
            Toast.LENGTH_SHORT).show());

默认注册按钮不可点击,当CheckBox被选中后则可点击注册,并修改注册按钮的样式。

View操作

RxCompoundButton中也封装了CompoundButton中例如setchecked()、toggle()等常用的操作,使用方式如下:

   RxView.clicks(btnLogin)
    .subscribe(o -> {
        RxCompoundButton.checked(cbContract).accept(true);
        RxCompoundButton.toggle(cbContract).accept(null);
    }));
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,263评论 25 707
  • 最近项目里面有用到Rxjava框架,感觉很强大的巨作,所以在网上搜了很多相关文章,发现一片文章很不错,今天把这篇文...
    Scus阅读 6,848评论 2 50
  • 原文地址:http://gank.io/post/560e15be2dca930e00da1083 前言 我从去年...
    AFinalStone阅读 2,180评论 5 23
  • 一、第42周计划及回顾 (一)第42周计划 (二)回顾 1、一周整体分析本周学习效率较高,我给自己制定了一条纪律:...
    巉岩与沙滩阅读 561评论 0 0
  • 通过使用正则表达式,可以: 测试字符串中的模式 替换文本 基于模式匹配从字符串中提取子字符串 正则表达式的应用领域...
    大头鬼w阅读 763评论 0 2