Skip to content

Instantly share code, notes, and snippets.

@dstd
Last active June 22, 2016 22:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dstd/80e6754d70c1ea3acea6dafd14c46e2e to your computer and use it in GitHub Desktop.
Save dstd/80e6754d70c1ea3acea6dafd14c46e2e to your computer and use it in GitHub Desktop.
KeyEvents interception made via window.callback swizzling
class KeyEventHook private constructor(
private val window: Window,
private val handleKeyEvent: (KeyEvent) -> Boolean,
private var originalCallback: Window.Callback)
: Window.Callback by originalCallback
{
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
if (handleKeyEvent(event))
return true
return originalCallback.dispatchKeyEvent(event)
}
fun unhook() {
if (originalCallback !is KeyEventHook)
window.callback = originalCallback
else if (window.callback is KeyEventHook)
window.callback = null
}
init {
window.callback = this
}
companion object {
fun hook(activity: Activity, handler: (KeyEvent) -> Boolean): KeyEventHook? {
val window = activity.window ?: return null
val callback = window.callback ?: return null
return KeyEventHook(activity, window, handler, callback)
}
}
}
class SomeView: View {
@JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : super(context, attrs, defStyleAttr) {}
private var _hook: KeyEventHook? = null
override fun onAttachedToWindow() {
super.onAttachedToWindow()
(this.context as? Activity)?.let {
_hook = KeyEventHook.hook(it) { event ->
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
setBackgroundColor(Color.RED)
true
} else
false
}
}
}
override fun onDetachedFromWindow() {
_hook?.unhook()
super.onDetachedFromWindow()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment