一些RxBinding使用场景

原创 2017年01月21日 15:09:21

本文已授权微信公众号:鸿洋(hongyangAndroid)原创首发。
转载请注明出处:http://blog.csdn.net/qq_17766199/article/details/54646011

其实一开头我就想说,RxBinding在一般情况没有使用的必要(我是谁?,我在哪?,我在干什么!)。但是在一些场景下,他是及其的简单方便,这篇就是分享一些我用到的地方。

1.RxBinding的好处

1.首先RxBinding是对Android View事件的扩展,它使得你可以对View事件使用RxJava的各种操作。

2.提供了与RxJava一致的回调,使得代码简洁明了。尤其是页面中充斥着大量的监听事件,各种各样的匿名内部类时。

3.几乎支持我们常用的所有控件及事件。(v4、v7、design、recyclerview等)另外每个库还有对应的Kotlin支持库。

2.RxBinding准备工作

添加相应的依赖(按需添加):

    compile 'com.jakewharton.rxbinding:rxbinding:1.0.0'
    compile 'com.jakewharton.rxbinding:rxbinding-support-v4:1.0.0'
    compile 'com.jakewharton.rxbinding:rxbinding-appcompat-v7:1.0.0'
    compile 'com.jakewharton.rxbinding:rxbinding-design:1.0.0'
    compile 'com.jakewharton.rxbinding:rxbinding-recyclerview-v7:1.0.0'
    compile 'com.jakewharton.rxbinding:rxbinding-leanback-v17:1.0.0'

3.RxBinding使用场景

1.防止按钮重复点击

这个应该是最常用的方法了。利用操作符throttleFirst取时间间隔内第一次点击事件。同样利用操作符throttleLastdebounce也可以实现。

RxView.clicks(mBt)
      .throttleFirst(1, TimeUnit.SECONDS)
      .subscribeOn(AndroidSchedulers.mainThread())
      .subscribe(new Action1<Void>() {
          @Override
          public void call(Void aVoid) {
             Log.i(TAG, "----button clicked----");
          }
 });

2.点击的多次监听

RxBinding文档中有这么一段话:

Mapping an observable to an Android event (e.g., view clicks) is a direct mapping. The library is not responsible for supporting multiple observables bound to the same view. Multiple listeners to the same view events can be achieved through operators like publish(), share(), or replay(). Consult the RxJava documentation for which is appropriate for the behavior that you want.

大意是说:Android是不能多次监听同一个点击事件。但利用RxJava的操作符,例如publish, sharereplay可以实现。而RxBinding恰好支持对点击事件的多次监听。这个说实话我没有用到过,但是总有人需要的,就说一下。

那么直接上代码:

        Observable<Void> observable= RxView.clicks(mBt1).share();

        Subscription s = observable.subscribe(new Action1<Void>() {
            @Override
            public void call(Void aVoid) {
                Log.i(TAG, "第一次");
            }
        });

        mCompositeSubscription.add(s);

        Subscription s1 = observable.subscribe(new Action1<Void>() {
            @Override
            public void call(Void aVoid) {
                Log.i(TAG, "第二次");
            }
        });

        mCompositeSubscription.add(s1);

打印结果:

I/ButtonClicksActivity: 第一次 
I/ButtonClicksActivity: 第二次

3.获取验证码倒计时

这个场景大家应该不陌生。比如注册账号时,我们需要获取验证码用来验证手机号码,在等待验证码时,界面会有倒计时提示我们重新获取之类的。

public class RegisterActivity extends AppCompatActivity {

    private static String TAG = "RegisterActivity";

    @BindView(R.id.bt)
    Button mBt;

    private Observable<Void> verifyCodeObservable;

    private static int SECOND = 20;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);
        ButterKnife.bind(this);
        initViews();
    }

    private void initViews() {

        verifyCodeObservable = RxView.clicks(mBt)
                .throttleFirst(SECOND, TimeUnit.SECONDS) //防止20秒内连续点击,或者只使用doOnNext部分
                .subscribeOn(AndroidSchedulers.mainThread())
                .doOnNext(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        RxView.enabled(mBt).call(false);
                    }
                });

        verifyCodeObservable.subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        Observable.interval(1, TimeUnit.SECONDS, AndroidSchedulers.mainThread())
                                .take(SECOND)
                                .subscribe(new Observer<Long>() {
                                    @Override
                                    public void onCompleted() {
                                        RxTextView.text(mBt).call("获取验证码");
                                        RxView.enabled(mBt).call(true);
                                    }

                                    @Override
                                    public void onError(Throwable e) {
                                        Log.e(TAG, e.toString());
                                    }

                                    @Override
                                    public void onNext(Long aLong) {
                                        RxTextView.text(mBt).call("剩余" + (SECOND - aLong) + "秒");
                                    }
                                });
                    }
                });

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        verifyCodeObservable.unsubscribeOn(AndroidSchedulers.mainThread()); //防止泄露
    }

}

代码很简单,就不过多的解释了。这里新用到了interval操作符,它是用来在给定的时间间隔发射从0开始的整数序列。例子中1s发射一次。

4.表单的验证。

比如常见的登录页面,只有当用户名,密码输入格式正确了,才可以去点击登录按钮。这个利用操作符combineLatest就可以巧妙实现。直接上代码:

public class LoginActivity extends AppCompatActivity {

    private static String TAG = "LoginActivity";

    @BindView(R.id.et_phone)
    EditText mEtPhone;
    @BindView(R.id.et_password)
    EditText mEtPassword;
    @BindView(R.id.bt_login)
    Button mBtLogin;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        ButterKnife.bind(this);
        initViews();
    }

    private void initViews() {

        Observable<CharSequence> ObservableName = RxTextView.textChanges(mEtPhone);
        Observable<CharSequence> ObservablePassword = RxTextView.textChanges(mEtPassword);

        Observable.combineLatest(ObservableName, ObservablePassword, new Func2<CharSequence, CharSequence, Boolean>() {
            @Override
            public Boolean call(CharSequence phone, CharSequence password) {
                return isPhoneValid(phone.toString()) && isPasswordValid(password.toString());
            }
        }).subscribe(new Action1<Boolean>() {
            @Override
            public void call(Boolean aBoolean) {
                RxView.enabled(mBtLogin).call(aBoolean);
            }
        });

        RxView.clicks(mBtLogin)
                .throttleFirst(1, TimeUnit.SECONDS)
                .subscribeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        Toast.makeText(LoginActivity.this, "登录成功!" ,Toast.LENGTH_SHORT).show();
                    }
                });

    }

    private boolean isPhoneValid(String phone) {
        return phone.length() == 11;
    }

    private boolean isPasswordValid(String password) {
        return password.length() >= 6;
    }

}

操作符combineLatest作用就是当多个Observables中的任何一个发射了一个数据时,通过一定的方法去组合多个Observables最新数据,然后发射最终结果。

在本例中两个输入框只要内容发生变化,就会发送Observable然后我们在Fun2中利用我们的验证方法去判断输入框中最新的内容,最终返回是否可点击的结果。

这个例子我们也可以看到简洁之处。我们使用RxTextView.textChanges(mEtPhone)就可以实现监听,而使用一般方法则像下面代码这样。(其实你可能只需要onTextChanged())

mEtPhone.addTextChangedListener(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) {

    }

    @Override
    public void afterTextChanged(Editable s) {

    }
});

4.RxBinding注意点

在上面的例子中,细心地你会发现,我会在onDestroy方法时手动的解除订阅,为的就是防止内存泄露,如果你觉得很麻烦的话,具体可以使用RxLifecycle,这里我就不过多的介绍了。

5.总结

RxBinding的实现其实比较简单,大家有兴趣可以去阅读一些源码。当然使用场景还有很多,大家可以去举一反三,我就不一一去说了。

最后本文的例子我已经全部上传到Github,大家可以自行参考。喜欢的话多多Star,点赞!

6.参考

  1. RxJava操作符之Share, Publish, Refcount

  2. RxJava-Android-Samples

版权声明:本文为博主原创文章,未经博主允许不得转载。http://blog.csdn.net/qq_17766199 举报

相关文章推荐

RxBinding的一些简单使用

前言:RxBinding 是 Jake Wharton 的一个开源库,它提供了一套在 Android 平台上的基于 RxJava的 Binding API。所谓 Binding,就是类似设置 OnCl...

RxBinding的使用,实现数据和View的绑定

rxbinding是一个开源项目,可以实现数据层与View层的绑定,当数据发生变化,View会自动更新UI。还有其他功能非常强大,github地址 https://github.com/ogacle...
  • ForAd
  • ForAd
  • 2015-10-23 11:26
  • 9945

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

RxAnroid之UI控件(View、Widget)RxBinding(同时异步执行多个Observable、同时异步执行多个任务)

RxBinding是Android种UI控件的Api 将RxJava应用于Android的好处就是更方便地组合各种异步操作,将Android中复杂的UI交互简单化,尤其是当触发多重UI事件时。还可以使...

初涉Rx套餐 之RxBinding(让你的事件流程更清晰)

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

Android学习笔记 十六 使用RxBinding响应控件的异步事件

RxBinding是Rx中处理控件异步调用的方式, 也是由Square公司开发, Jake负责编写. 通过绑定组件, 异步获取事件, 并进行处理. 编码风格非常优雅. 让我来讲解一下如何使用, 本...

RxJava 和 RxAndroid 四(RxBinding的使用)

@zhaoyanjun521 2016-05-27 19:42 字数 3634 阅读 120 rxjava rxandroid rxBinding 赵彦军 android 对Rxjava不熟...

使用RxBinding处理控件异步调用

RxBinding是Rx中处理控件异步调用的方式, 也是由Square公司开发, Jake负责编写. 通过绑定组件, 异步获取事件, 并进行处理. 编码风格非常优雅. 让我来讲解一下如何使用, 本文含...

细数RxBinding的各种优雅响应式绑定

RxBinding出自Square公司的Jake Wharton大神之手,往往是结合RxJava一起使用。RxBinding的核心是RxView,它包含:attaches、detaches、click...

扩展 Rxbinding,打造自定义监听多控件接口

使用 Rxbinding 可以优雅的令我们完成一对一的控件监听效果,但是我们时常会在项目中遇到类似如下的需求:只有当两个控件满足同时满足一定的需求时才使得另一个控件状态改变,也就是一个控件需要同时监听...

RxJava 和 RxAndroid 四(RxBinding的使用)

本文转载自:http://www.cnblogs.com/zhaoyanjun/p/5535651.html 对Rxjava不熟悉的同学可以先看我之前写的几篇文章 RxJava 和...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)