RxJava使用场景

准备工作

  • 依赖
    1
    compile 'io.reactivex:rxjava:1.1.0'
    compile 'io.reactivex:rxandroid:1.1.0'
    compile 'com.trello:rxlifecycle:0.4.0'
    compile 'com.jakewharton.rxbinding:rxbinding:0.3.0'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class BaseActivity extends AppCompatActivity {
private CompositeSubscription _compositeSubscription = new CompositeSubscription();

@Override
protected void onDestroy() {
super.onDestroy();
if(_compositeSubscription.isUnsubscribed()){
_compositeSubscription.unsubscribe();
}
}

public void addSubscription(Subscription subscription){
_compositeSubscription.add(subscription);
}

}

验证码倒计时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class CountDownDemoActivity extends AppCompatActivity {
Observable<Void> verifyCodeObservable;
@Bind(R.id.btn_verify_code)
Button btnVerifyCode;

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


verifyCodeObservable = RxView.clicks(btnVerifyCode).throttleFirst(60, TimeUnit.SECONDS).subscribeOn(AndroidSchedulers.mainThread());

verifyCodeObservable.subscribe(aVoid -> {
Observable.timer(0, 1000, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread()).take(60).subscribe(aLong -> {
btnVerifyCode.setText(60 - aLong + "'");
}, (error) -> {
}, () -> {
btnVerifyCode.setText("获取验证码");
}
);
}
);
}


@Override
protected void onDestroy() {
super.onDestroy();
unSubscribeObservables();
}

private void unSubscribeObservables() {
verifyCodeObservable.unsubscribeOn(AndroidSchedulers.mainThread());
}
}

分析:

  • RxView.clicks(btn_verify_code)创建Observable对象是采用RxBinding,throttleFirst用来防止60秒内连续点击
  • 通过timer控制按钮上面倒计时描述
  • timer倒计时完毕重置按钮文字
  • onDestroy的时候unSubscribe

控制检索频率

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class SearchActivity extends BaseActivity {
private static final String TAG = "SearchActivity";
@Bind(R.id.et_search)
EditText etSearch;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
ButterKnife.bind(this);
addSubscription(RxTextView.textChanges(etSearch).debounce(300, TimeUnit.MILLISECONDS).filter(charSequence -> !TextUtils.isEmpty(charSequence))
.subscribe(charSequence -> {
Log.d(TAG, "call() called with: " + "charSequence = [" + charSequence + "]");
}));
}

}

分析:

  • debounce控制每300ms获取当前输入框的值
  • filter过滤空的字符串
  • addSubscription的好处是:onDestroy的时候父类_compositeSubscription会统一unSubscribe

表单验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class FormValidateActivity extends BaseActivity {
@Bind(R.id.etUserName)
EditText etUserName;
@Bind(R.id.etPassWord)
EditText etPassWord;
@Bind(R.id.btn)
Button btn;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.activity_form_validate);
ButterKnife.bind(this);

//方案1
Observable<CharSequence> _nameChangeObservable = RxTextView.textChanges(etUserName);
Observable<CharSequence> _pwdChangeObservable = RxTextView.textChanges(etPassWord);
addSubscription(Observable.combineLatest(_nameChangeObservable, _pwdChangeObservable, new Func2<CharSequence, CharSequence, Boolean>() {
@Override
public Boolean call(CharSequence userName, CharSequence userPwd) {
return !TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPwd);
}
}).subscribe(new Action1<Boolean>() {
@Override
public void call(Boolean isValid) {
btn.setEnabled(isValid);
}
}));

//简化版
addSubscription(Observable.combineLatest(
RxTextView.textChanges(etUserName)
, RxTextView.textChanges(etPassWord)
, (userName, userPwd) -> !TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPwd)
).subscribe(isValid -> btn.setEnabled(isValid)));
}
}
  • 两个输入框只要内容变化,就会发送Observable
  • subscribe只需要根据上面Func2的返回值设置Button是否可点
  • 如果有其他针对用户名和密码的校验,也可以在Func2中做

模拟两个数实时运算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class AdditionActivity extends BaseActivity {
@Bind(R.id.etNum1)
EditText etNum1;
@Bind(R.id.etNum2)
EditText etNum2;
@Bind(R.id.tvResult)
TextView tvResult;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_addtion);
ButterKnife.bind(this);

addSubscription(Observable.combineLatest(
RxTextView.textChanges(etNum1).map(convertString2Int()),
RxTextView.textChanges(etNum2).map(convertString2Int()),
(num1, num2) -> num1 + num2
).subscribe(
integer -> tvResult.setText(integer + "")
));
}

@NonNull
private Func1<CharSequence, Integer> convertString2Int() {
return charSequence -> {
try {
return Integer.parseInt(charSequence.toString());
} catch (Exception e) {
return 0;
}
};
}
}

分析:

  • 两个输入框只要内容变化,就会发送Observable
  • subscribe中显示和,如果转换异常,清空结果中的数字
文章目录
  1. 1. 准备工作
  2. 2. 验证码倒计时
  3. 3. 控制检索频率
  4. 4. 表单验证
  5. 5. 模拟两个数实时运算