Как возобновить приостановленный CountDownTimer в Котлине - PullRequest
0 голосов
/ 08 ноября 2019

Идея в том, чтобы сделать шахматные часы. Но проблема заключается в возобновлении приостановленного экземпляра CountDownTimer без сброса или создания нового.

Первое действие - это прикосновение к «белой кнопке», и вызывается метод «startTimerBlack»: запускается черный таймер,таймер белого приостановлен.

При касании «черной кнопки» вызывается «startTimerWhite»: запускается таймер белого, пауза черного таймера.

При повторном нажатии белой кнопкичерный таймер должен возобновиться, но это не так.

class MainActivity : AppCompatActivity() {
    enum class TimerState {
        Stopped, Paused, Running
    }

    private lateinit var timerWhite: CountDownTimer
    private lateinit var timerBlack: CountDownTimer
    private var timerStateWhite = TimerState.Stopped
    private var timerStateBlack = TimerState.Stopped
    private var secondsRemaining = 0L

    override fun onCreate(savedInstanceState: Bundle?) {
        requestWindowFeature(Window.FEATURE_NO_TITLE)
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        buttonWhite.setOnClickListener { v ->
            println("white")
            startTimerBlack()
        }
        buttonBlack.setOnClickListener { v ->
            println("black")
            startTimerWhite()
        }
    }

    private fun startTimerWhite() {
        if(timerStateBlack != TimerState.Stopped) {
            timerBlack.cancel()
            timerStateBlack = TimerState.Paused
        }

        timerStateWhite = TimerState.Running
        timerWhite = object : CountDownTimer(1000 * 1000, 1000) {
            override fun onTick(millisUntilFinished: Long) {
                secondsRemaining = millisUntilFinished / 1000
                buttonWhite.text = secondsRemaining.toString()
            }
            override fun onFinish() {}
        }.start()
    }

    private fun startTimerBlack() {
    if(timerStateWhite != TimerState.Stopped) {
        timerWhite.cancel()
        timerStateWhite = TimerState.Paused
    }

    timerStateBlack = TimerState.Running
    timerBlack = object : CountDownTimer(secondsRemaining, 1000) {
        override fun onTick(millisUntilFinished: Long) {
            secondsRemaining = millisUntilFinished / 1000
            buttonBlack.text = secondsRemaining.toString()
        }

        override fun onFinish() {

        }
    }.start()
  }
}

Ответы [ 2 ]

0 голосов
/ 08 ноября 2019

Я думаю, что это может быть сделано в течение одного Thread и времени для обоих игроков. Так как это обрабатывается по-другому. Проверьте этот очень простой код, чтобы сделать это.

class MainActivity : AppCompatActivity() {
    private val DELAY = TimeUnit.SECONDS.toMillis(3)
    private val chessTimer = ChessTimer("Sample")

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        startTask()
        chessTimer.start()
    }

    private fun startTask() {
        Handler(Looper.getMainLooper()).postDelayed({
            chessTimer.changeTime()
            startTask()
        }, DELAY)
    }

    private class ChessTimer(name: String) : Thread(name) {
        var time1 = TimeUnit.MINUTES.toMillis(3)
        var time2 = TimeUnit.MINUTES.toMillis(3)

        var active: Boolean = true
        var startTime : Long = 0

        override fun run() {
            var whichAction = active

            while (true) {
                synchronized(this) {
                    if (active != whichAction) {
                        /**
                         * Action was changed!
                         */
                        val delta = System.currentTimeMillis() - startTime
                        Log.d("Sample", "Current time: ${System.currentTimeMillis()} Delta $delta")
                        if (whichAction) time1 -= delta
                                else time2 -= delta

                        whichAction = active
                        startTime = System.currentTimeMillis()
                        Log.d(
                            "Sample", "Time one $time1." +
                                    " Time second $time2"
                        )
                    }

                }
            }
        }

        override fun start() {
            startTime = System.currentTimeMillis()
            active = true
            super.start()
        }

        fun changeTime() {
            synchronized(this) {
                Log.d("Sample", "Time: ${System.currentTimeMillis()} ")
                active = !active
            }
        }
    }
}
0 голосов
/ 08 ноября 2019
timerWhite = object : CountDownTimer(1000 * 1000, 1000)

Если я прав, вышеприведенное всегда сбрасывает ваш secondsRemaining на 999000 / 1000 = 999, когда timerWhite начинает свой первый тик. В результате whiteTimer всегда перезапускается со значением 1000 с, а blackTimer всегда запускается в то время, которое осталось после остановки whiteTimer.

Если я правильно понял шахматные часы, у вас должно быть сохранено отдельное время для каждого таймера,Как ниже:

private var whiteSecondsRemaining = 1000
private var blackSecondsRemaining = 1000
...
timerWhite = object : CountDownTimer(whiteSecondsRemaining , 1000) {
    // update whiteSecondsRemaining in onTick()
}
...
timerBlack = object : CountDownTimer(blackSecondsRemaining , 1000) {
    // update blackSecondsRemaining in onTick()
}
...