Reputation: 333
I hava created a simple timer, which count from 0 to 30 with interval of 1 second. I want to achive the same, but it must be count from 30 to 0 and it must be done with a RxJava. Can someone provide me sample convertion?
Here is my code:
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) {
}
});
}
Upvotes: 1
Views: 1042
Reputation: 69997
It doesn't have to be complicated:
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);
}
});
Upvotes: 2
Reputation: 11
Hm, i don't know how to use reverse range, but the simple way is to use following:
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);
and unsubscribe when onStop() invoked
@Override
public void onStop(){
subscription.unsubscribe();
}
or without 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);
}
});
and of course apply schedulers for observable
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
Upvotes: 0