【发布时间】:2017-12-23 13:40:11
【问题描述】:
我正在编写一个使用 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 方法已被调用。然后当运行时钟到期时,即使新时钟仍在运行,新游戏也会被冻结。
我是 android 新手,我不明白这是怎么回事。我原以为活动结束时时钟会被破坏。我已经测试了我对日志消息发生了什么的想法,并确认时钟在调用 onDestroy 之后运行。我还重写了 onDetachedFromWindow 以停止时钟,它使问题消失了,但这是矫枉过正。如果用户接到电话,它也会停止时钟,不是吗,这不是我想要的。
你能建议如何最好地完成我想要的吗?没有办法从活动中访问时钟吗?我曾想过在 onDestroy 中发出一些事件,并让 ChessClock 监听它,但我还不知道如何编写自定义事件和监听器。有没有更简单的方法?
【问题讨论】:
-
我是 kotlin 语言的新手,但如果你可以将 java 代码转换为 kotlin,我将向你展示如何获取后退按钮单击侦听器
-
@BrunoFerreira 是的,那太好了。我不是一个java程序员,但我应该能够转换代码。
-
检测java中的后退只需执行此 public void onBackPressed() { super.onBackPressed();} 如果我想在后退按钮被触发之前做一些事情,我在 super 之前添加代码。 onBackPressed();.
-
@BrunoFerreira 但是 onBackPressed 在活动中。我如何从那里访问时钟?视图似乎没有 onBackPressed 函数。