使用JS界面在Kotlin
WebView
上工作,我的Web应用程序需要从本机端检测KeyEvent.KEYCODE_BACK
事件,以在显示时关闭Web应用程序对话框。如果取消了对话框,则我不应该在本地执行任何操作(将true还原为超级),否则,我需要完成网络视图活动(将false还原为super)。为了了解我的意图,请阅读以下代码,该代码是我在自定义WebView
上实现的提示,
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
if (event.action == KeyEvent.ACTION_DOWN) {
when (keyCode) {
KeyEvent.KEYCODE_BACK -> {
this.evaluateJavascript("onDeviceBackPressed();", ValueCallback {
if (it == "1") {
// "Web app consumed onDeviceBackPressed event!"
} else {
// "Web app did not consume onDeviceBackPressed event!"
// super.onKeyDown(keyCode, event) won't work
}
})
// I am required to make the return call wait
// return true/false base on status returned by js func
}
}
}
return super.onKeyDown(keyCode, event)
}
但是我知道不可能异步等待超级调用。我该如何以其他方式处理这种情况?
答案 0 :(得分:1)
您可以在等待JS的第一个按键按下事件期间使用KeyEvent,然后在获取结果时重新使用它。
我曾经对触摸事件使用过这样的技巧,所以它应该可以工作。
var delayedKeyCode : Int? = null
var delayedKeyEvent : KeyEvent? = null
var keyDownJSResult : String? = null
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
if (event.action == KeyEvent.ACTION_DOWN) {
when (keyCode) {
KeyEvent.KEYCODE_BACK -> {
// see if there's "result" provided from JS
keyDownJSResult?.let{
keyDownJSResult = null // wipe out result so it's not triggered twice
if (it == "1") {
// "Web app consumed onDeviceBackPressed event!"
return true
} else {
// "Web app did not consume onDeviceBackPressed event!"
return super.onKeyDown(keyCode, event)
}
}
// otherwise store keyDown arguments for later and trigger JS
delayedKeyCode = keyCode
delayedKeyEvent = event
this.evaluateJavascript("onDeviceBackPressed();", ValueCallback {
// when JS returns value, trigger this onKeyDown event again
val oldCode = delayedKeyCode
val oldEv = delayedKeyEvent
delayedKeyCode = null
delayedKeyEvent = null
keyDownJSResult = it
onKeyDown(oldCode, oldEv)
})
// always consume event when waiting for JS result
return true
}
}
}
return super.onKeyDown(keyCode, event)
}
答案 1 :(得分:0)
最后,我有一点技巧可以解决我的问题,
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
if (event.action == KeyEvent.ACTION_DOWN) {
when (keyCode) {
KeyEvent.KEYCODE_BACK -> {
this.evaluateJavascript("onDeviceBackPressed();", ValueCallback {
if (it == "1") {
// consumed by web app, do nothing
} else {
// not consumed by web app, fire explicit back press event
mContext.onBackPressed()
}
})
return true
}
}
}
return super.onKeyDown(keyCode, event)
}