Intereting Posts
Retrofit-Vertx с RxJava2 в Kotlin IllegalStateException message == null Многопоточность с использованием Kotlin Corouts значение переменной получает значение null в модификации RecyclerView анимация элемента, onAnimationFinished, но не onAnimationStarted. Зачем? Библиотека Android kotlin и Room Persistences не строит Kotlin: реализация LinkedList Kotlin создает результат запроса для анализа репозиториев github Неожиданная разница типов между эквивалентным Java и кодом потока Kotlin Котлинское переопределение функции Kotlin mutableList () возвращается с карты :: getOrElse не выставляет add () Android показывает, казалось бы, безобидное предупреждение при воспроизведении звука? Не удается вызвать StartActivityForResult в Анко Текстовый объект объекта Kotlin, реализующий дикий кардочесальный, саморегуляторный общий интерфейс Как использовать Realm в библиотеке В Kotlin, как вы можете ограничить выбор в свободно Builder для разных видов настроек

Кнопка Detect Back Нажмите кнопку в Android View

Я пишу приложение для игры, в котором используется класс ChessClock. У каждого из двух игроков есть часы. Часы посылают себе поток сообщений каждую десятую секунды, а если они работают, уменьшайте оставшееся время. Когда время истекает, часы вызывают метод в родительской группе представлений, которая останавливает часы и устанавливает флаг, который вызывает игнорирование других событий касания, чтобы пользователи больше не могли перемещать куски. Я пишу в kotlin, но я думаю, что это будет понятно и для Java-программиста:

class ChessClock : TextView { constructor(context: Context) : super(context) constructor(context:Context, p:String) : this(context) { player = p } var player = "" val RUNNING = 0 val PAUSED = 1 val IDLE = 2 val EXPIRED = 3 val mInterval = 100L var mTime = 0L // in milliseconds var mState = IDLE val mHandler = Handler() val mUpdateTimeTask = object : Runnable { override fun run() { if (mState == RUNNING) showTime() mHandler.postDelayed(this, mInterval) } } // override fun onDetachedFromWindow() { // super.onDetachedFromWindow() // stop() // } fun setTime(minutes:Long) { mTime = 1000*60*minutes // minutes to milliseconds mState = IDLE setTextColor(getResources().getColor(R.color.colorIdle)) showTime() mUpdateTimeTask.run() } fun pause() { mState = PAUSED setTextColor(getResources().getColor(R.color.colorPaused)) } fun start() { mState = RUNNING setTextColor(getResources().getColor(R.color.colorRunning)) } fun expire() { mState = EXPIRED setTextColor(getResources().getColor(R.color.colorExpired)) model.timeout(player) val aboyne = parent as AboyneView aboyne.gameOver(false) } fun toggle() { if (mState == PAUSED) start() else if (mState == RUNNING) pause() } fun stop() { mHandler.removeCallbacks(mUpdateTimeTask) } fun showTime() { val tenths = (mTime % 1000) / 100 var seconds = mTime / 1000 val minutes = seconds % 3600 / 60 seconds %= 60 if (minutes >= 1) setText(String.format("%02d:%02d",minutes, seconds)) else setText(String.format("%01d:%02d:%01d",minutes, seconds, tenths)) if (mState != RUNNING) return if (mTime > 0) mTime -= mInterval else expire() } } 

Это прекрасно работает, но если пользователь нажимает кнопку «Назад», а затем запускает новую игру, часы, похоже, продолжают работать, хотя метод onDestroy активности был вызван. Затем, когда работающие часы истекают, новая игра замерзает, даже если новые часы все еще работают.

Я новичок в андроиде, и я не понимаю, как это происходит. Я бы подумал, что часы будут уничтожены, когда будет активность. Я проверял свои идеи о том, что происходит с сообщениями журнала, и подтвердил, что часы, запускаемые после onDestroy, вызываются. Я также переопределил onDetachedFromWindow, чтобы остановить часы, и это заставляет проблему уйти, но это слишком много. Он также остановит часы, если пользователь получит телефонный звонок, не так ли, и это не то, что я хочу.

Можете ли вы предложить, как наилучшим образом выполнить то, что я хочу? Не существует способа получить доступ к часам от активности? Я думал об испускании какого-либо события в onDestroy и прослушивании ChessClock, но я еще не знаю, как писать пользовательские события и прослушиватели. Есть ли более простой способ?

Я не знаю, как это сделать в Kotlin, но в java. Вы можете установить Timer, выполнив timertask каждые X millis, а затем отмените его, если нужно, вызовите mTimer.cancel (). Вы должны попробовать использовать его вместо mHandler.postDelayed (это, mInterval)

вот как вы это делаете: как вызвать функцию после задержки в Котлине?

Я не понимал, как сделанные предложения могут решить мою проблему, но я придумал клочок.

Я сделал глобальную переменную BACK_BUTTON, инициализированную на false . В своей деятельности я onDestroy чтобы установить BACK_BUTTON в true . Затем я изменил код ChessClock, чтобы проверить BACK_BUTTON:

 val mUpdateTimeTask = object : Runnable { override fun run() { if (BACK_BUTTON) expire() else { if (mState == RUNNING) showTime() mHandler.postDelayed(this, mInterval) } } 

Не отличное решение, но это нужно будет сделать, пока я не выясню пользовательские события. Насколько я вижу, пользовательское событие и пользовательский прослушиватель событий – единственный чистый способ сделать это.