Chromebook聊天应用:如何判断onResume由表情弹窗触发?
解决方案
1. 直接捕获表情弹窗唤起快捷键
既然表情弹窗是通过Search + Shift + Enter组合键触发的,直接在Activity中监听这个快捷键组合,标记全局状态来区分onResume的触发来源:
private var isEmojiPopupTriggered = false override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { val isSearchKey = keyCode == KeyEvent.KEYCODE_SEARCH val isShiftPressed = event?.isShiftPressed == true val isEnterKey = keyCode == KeyEvent.KEYCODE_ENTER if (isSearchKey && isShiftPressed && isEnterKey) { isEmojiPopupTriggered = true } return super.onKeyDown(keyCode, event) } override fun onResume() { super.onResume() if (isEmojiPopupTriggered) { // 这里处理表情弹窗返回后的逻辑 isEmojiPopupTriggered = false // 重置标记 } }
这个方法完全不受表情加载速度影响,是最直接可靠的判断方式。
2. 利用前后台切换时间差+输入框布局监听
如果快捷键存在兼容性问题,可通过onPause和onResume的时间差过滤非表情弹窗的后台切换,再监听输入框布局变化(表情插入会触发布局更新):
private var inputView: EditText? = null private var pauseTimestamp: Long = 0 override fun onPause() { super.onPause() pauseTimestamp = System.currentTimeMillis() } override fun onResume() { super.onResume() val timeDiff = System.currentTimeMillis() - pauseTimestamp // 表情弹窗的打开/关闭通常在1秒内完成 if (timeDiff < 1000) { inputView?.viewTreeObserver?.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { override fun onGlobalLayout() { inputView?.viewTreeObserver?.removeOnGlobalLayoutListener(this) val currentText = inputView?.text.toString() // 结合你原有的hasEmojis方法判断,或直接处理表情插入逻辑 } }) } }
3. 拦截输入法的文本插入事件
通过自定义InputConnectionWrapper,从源头捕获表情插入行为:
private var isEmojiInserted = false override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection { val baseConn = super.onCreateInputConnection(outAttrs) return object : InputConnectionWrapper(baseConn, true) { override fun commitText(text: CharSequence?, newCursorPosition: Int): Boolean { if (text != null && hasEmojis(text.toString())) { isEmojiInserted = true } return super.commitText(text, newCursorPosition) } } } override fun onResume() { super.onResume() if (isEmojiInserted) { // 处理表情插入后的逻辑 isEmojiInserted = false } }
内容的提问来源于stack exchange,提问作者rosu alin
相关产品推荐
相关产品推荐

