首页 > 解决方案 > 有时,打开的软键盘会在短时间内减少 WindowVisibleDisplayFrame 区域,而不是软键盘放置所需的区域

问题描述

我需要键盘覆盖屏幕上的主要内容,但一些视图应该放在键盘上方。

因此,我将 WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING 用于我的活动,并使用透明的 popupWindow 和 OnGlobalLayoutListener 来了解键盘打开事件何时发生以及此键盘的高度。有用。

但有时 onGlobalLayout() 方法中的 popupView.getWindowVisibleDisplayFrame(rect) 计算的高度比我预期的要小(这意味着键盘更高(2 倍)但你在屏幕上看不到它,它看起来像往常一样)和短时间(20 - 60 毫秒,平均 23 毫秒)被称为具有正确 WindowVisibleDisplayFrame 值的新 onGlobalLayout() 方法。我用 postDelay 修复它。但这是一个黑客。

而且我想知道它为什么会发生以及它依赖于什么,以使我的代码更清晰。

PS 我检查了https://github.com/siebeprojects/samples-keyboardheight并在日志中看到了同样的问题。

我的代码:

internal class SoftKeyboardChangeHeightHandler(
        val parentActivity: Activity,
        val viewsForTranslation: View,
        val keyboardChangeHeightListener: SoftKeyboardChangeHeightListener? = null
    ) : PopupWindow(parentActivity.applicationContext), ViewTreeObserver.OnGlobalLayoutListener {
        private val decorView = parentActivity.window.decorView
        private val popupView = View(parentActivity.applicationContext)
        private var portraitHeightMax = 0
        private var landscapeHeightMax = 0
        private var keyboardHeight = 0
    
        init {
            contentView = popupView
            setBackgroundDrawable(ColorDrawable(0))
            width = 0
            height = ViewGroup.LayoutParams.MATCH_PARENT
            softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
            inputMethodMode = INPUT_METHOD_NEEDED
        }
    
        fun onResume() {
            popupView.viewTreeObserver.addOnGlobalLayoutListener(this)
            if (!isShowing) {
                decorView.post { showAtLocation(decorView, Gravity.NO_GRAVITY, 0, 0) }
            }
        }
    
        fun onPause() {
            popupView.viewTreeObserver.removeOnGlobalLayoutListener(this)
        }
    
        override fun onGlobalLayout() {
            val rect = Rect()
            popupView.getWindowVisibleDisplayFrame(rect)
            keyboardHeight = if (getScreenOrientation() == Configuration.ORIENTATION_PORTRAIT) {
                if (rect.bottom > portraitHeightMax) {
                    portraitHeightMax = rect.bottom
                }
                portraitHeightMax - rect.bottom
            } else {
                if (rect.bottom > landscapeHeightMax) {
                    landscapeHeightMax = rect.bottom
                }
                landscapeHeightMax - rect.bottom
            }
            val screenSize = Point()
            parentActivity.windowManager.defaultDisplay.getSize(screenSize)
            L.info {
                "keyboardHeight = $keyboardHeight" +
                    "\nvisibleDisplay.bottom = ${rect.bottom}" +
                    "\nheightMax = $portraitHeightMax\ndecorViewHeight = ${decorView.height} " +
                    "\nscreensizeY = ${screenSize.y}"
            }
    
            val callBack = {
                keyboardChangeHeightListener
                viewsForTranslation.translationY = -keyboardHeight.toFloat()
            }
            viewsForTranslation.removeCallbacks(callBack)
            viewsForTranslation.postDelayed(callBack, 100)
        }
    }

日志:

2021-08-19 15:18:33.021 SoftKeyboardChangeHeightHandler:  keyboardHeight = 685 // open
        visibleDisplay.bottom = 1403
        heightMax = 2088
        decorViewHeight = 2220
        screensizeY = 2088 

2021-08-19 15:18:34.134 SoftKeyboardChangeHeightHandler:  keyboardHeight = 0 //close correct size
        visibleDisplay.bottom = 2088
        heightMax = 2088
        decorViewHeight = 2220
        screensizeY = 2088
   
 2021-08-19 15:18:34.762 SoftKeyboardChangeHeightHandler:  keyboardHeight = 1370 // open with size *2
        visibleDisplay.bottom = 718
        heightMax = 2088
        decorViewHeight = 2220
        screensizeY = 2088

 2021-08-19 15:18:34.781 SoftKeyboardChangeHeightHandler:  keyboardHeight = 685 //correct size
        visibleDisplay.bottom = 1403
        heightMax = 2088
        decorViewHeight = 2220
        screensizeY = 2088

 2021-08-19 15:18:38.513 SoftKeyboardChangeHeightHandler:  keyboardHeight = 0
        visibleDisplay.bottom = 2088
        heightMax = 2088
        decorViewHeight = 2220
        screensizeY = 2088

 2021-08-19 15:18:38.535 SoftKeyboardChangeHeightHandler:  keyboardHeight = 0
        visibleDisplay.bottom = 2088
        heightMax = 2088
        decorViewHeight = 2220
        screensizeY = 2088 2021-08-19

 15:18:42.049 SoftKeyboardChangeHeightHandler:  keyboardHeight = 685
        visibleDisplay.bottom = 1403
        heightMax = 2088
        decorViewHeight = 2220
        screensizeY = 2088

标签: androidandroid-softkeyboardandroid-popupwindowwindow-soft-input-modeongloballayoutlistener

解决方案


推荐阅读