Android将基本计时器转换为RxJava

时间:2017-02-19 16:43:08

标签: android rx-java observable

我hava创建了一个简单的计时器,从0到30计数,间隔为1秒。 我想要达到相同的目标,但它必须从30计数到0,并且必须使用RxJava完成。有人能为我提供样品转换吗?

这是我的代码:

 TextView timerTextView;
long startTime = 0;

//runs without a timer by reposting this handler at the end of the runnable
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {

    @Override
    public void run() {
        long millis = System.currentTimeMillis() - startTime;
        int seconds = (int) (millis / 1000);
        int minutes = seconds / 60;
        seconds = seconds % 60;

        timerTextView.setText(String.format("%d:%02d", minutes, seconds));

        timerHandler.postDelayed(this, 500);
    }
};

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    timerTextView = (TextView) findViewById(R.id.textView);

    Button b = (Button) findViewById(R.id.button);
    b.setText("start");
    b.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            Button b = (Button) v;
            if (b.getText().equals("stop")) {
                timerTextView.setText("0:00");
                timerHandler.removeCallbacks(timerRunnable);
                b.setText("start");
            } else {
                startTime = System.currentTimeMillis();
                timerHandler.postDelayed(timerRunnable, 0);
                b.setText("stop");
            }
        }
    });

    timerTextView.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) {
            if(timerTextView.getText().toString().equals("0:30")){
                Toast.makeText(MainActivity.this, "End of time!", Toast.LENGTH_SHORT).show();
            }
        }

        @Override
        public void afterTextChanged(Editable s) {
        }
    });
}

2 个答案:

答案 0 :(得分:2)

它不必复杂:

Observable.interval(1, TimeUnit.SECONDS, AndroidSchedulers.mainThread())
.take(31) // 0, 1, 2, ..., 30
.map(new Func1<Long, Integer>() {
     @Override public Integer call(Long value) {
         return 30 - value.intValue();
     }
})
.subscribe(new Action1<Integer>() {
     @Override public void call(Integer value) {
          System.out.println(value);
     }
});

答案 1 :(得分:0)

嗯,我不知道如何使用反向范围,但简单的方法是使用以下内容:

 final int startCount = 30;
 final Observable<Integer> observable = Observable
            .range(0, startCount)
            .concatMap(
                    i -> Observable.just(i)
                            .delay(1, TimeUnit.SECONDS)
                            .map(it -> startCount - it)
            );

 final Subscription subscription = observable.subscribe(System.out::println);

并在调用onStop()时取消订阅

@Override
public void onStop(){
    subscription.unsubscribe();
}

或没有lambda:

 final int startCount = 30;
 final Observable<Integer> observable = Observable
            .range(0, startCount)
            .concatMap(new Func1<Integer, Observable<? extends Integer>>() {
                           @Override
                           public Observable<? extends Integer> call(Integer integer) {
                               return Observable.just(integer)
                                       .delay(1, TimeUnit.SECONDS)
                                       .map(new Func1<Integer, Integer>() {
                                           @Override
                                           public Integer call(Integer integer) {
                                               return startCount - integer;
                                           }
                                       });
                           }
                       }
            );

 final Subscription subscription = observable
            .subscribe(new Action1<Integer>() {
                @Override
                public void call(Integer integer) {
                    System.out.println(integer);
                }
            });

当然可以将schedulers应用于可观察的

.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())