Как уведомить Observable, когда CountdownTimer завершится

У меня есть собственный Android TextView, который показывает количество времени, оставшееся в игре, через CountDownTimer.

class CountdownTextView(context: Context, attrs: AttributeSet) : TextView(context, attrs) {

    private lateinit var countDownTimer: CountDownTimer
    private lateinit var onFinishObservable: Observable<Unit>

    fun setTime(initTime: Int) {
        this.text = "$initTime:00"
        countDownTimer = object : CountDownTimer((initTime *1000).toLong(), 1000) {
            override fun onTick(millisUntilFinished: Long) {
            val minutes = millisUntilFinished / 60000
            val seconds = (millisUntilFinished % 60000) / 1000
            if (seconds / 10 > 0) {
                text = "$minutes:${(millisUntilFinished % 60000) / 1000}"
            } else {
                text = "$minutes:0${(millisUntilFinished % 60000) / 1000}"
            }
        }

        override fun onFinish() {

        }
    }


    fun startCountdown() {
        countDownTimer.start()
    }
}

Как настроить наблюдаемую, которая выдает значение при вызове метода onFinish() счетчика countDownTimer? Мне это нужно, чтобы в основном действии я мог подписаться на этот наблюдаемый объект и выполнить необходимые действия, когда истечет время обратного отсчета.


person Arsala Bangash    schedule 30.07.2017    source источник


Ответы (1)


Вы можете указать Тема.

val onFinishObservable = CompletableSubject.create()

override fun onFinish() {
    onFinishObservable.onComplete()
}

Или вы можете использовать Rx для таймера вместо CountDownTimer.

fun countDownTimer(
        time: Long, timeUnit: TimeUnit = TimeUnit.MILLISECONDS,
        tick: Long = 1, tickUnit: TimeUnit = TimeUnit.MILLISECONDS
): Observable<Long> {
    val timeNanos = timeUnit.toNanos(time).also { require(it >= 0) }
    val tickNanos = tickUnit.toNanos(tick).also { require(it > 0) }
    val ticks = timeNanos / tickNanos
    return Observable
        .intervalRange(
            1L, ticks, timeNanos % tickNanos, tickNanos, TimeUnit.NANOSECONDS)
        .map { ticks - it }
        .startWith(ticks)
}

fun start(time: Long, timeUnit: TimeUnit = TimeUnit.SECONDS): Completable {
    timerSubscription?.dispose()
    val timer = countDownTimer(time, timeUnit, tickUnit = TimeUnit.SECONDS)
    timerSubscription = timer.subscribe {
        text = String.format("%d:%02d", it / 60, it % 60)
    }
    return timer.ignoreElements()
}

В любом случае вызывающий абонент может подписаться на этот Completable.

person ephemient    schedule 30.07.2017
comment
Я использовал завершаемый предмет, и он работал отлично. Так много нужно узнать о реактивных расширениях! 1. Повысит ли теоретически производительность использование RX для таймера обратного отсчета? 2. Мне трудно понять, как будет завершен RxTimer. - person Arsala Bangash; 31.07.2017
comment
О, nvm val timeNanos = timeUnit.toNanos(time).also { require(it ›= 0) } val tickNanos = tickUnit.toNanos(tick).also { require(it › 0) } Должен помочь - person Arsala Bangash; 31.07.2017
comment
@ArsalaBangash В этом случае нет прямой выгоды от использования таймера на основе Rx, но он более гибкий и может быть полезен, если вы подключаете его к другим вещам. - person ephemient; 31.07.2017