安卓webView輸入法遮擋問題解決

語言: CN / TW / HK

問題

在實際專案開發中遇到一個webView中新增input框被輸入法遮擋問題,尤其小米手機設定adjustPan和adjustResize都無法適配。後搜尋查到此類。問題解決。做此記錄 ``` import android.app.Activity import android.content.Context import android.graphics.Rect import android.view.View import android.widget.FrameLayout

class GlobalLayoutUtils(activity: Activity, private var isImmersed: Boolean = true) {

// 當前介面根佈局,就是我們設定的 setContentView()
private var mChildOfContent: View
private var frameLayoutParams: FrameLayout.LayoutParams
// 變化前的試圖高度
private var usableHeightPrevious = 0

init {
    val content: FrameLayout = activity.findViewById(android.R.id.content)
    mChildOfContent = content.getChildAt(0)

    // 添加布局變化監聽
    mChildOfContent.viewTreeObserver.addOnGlobalLayoutListener {
        possiblyResizeChildOfContent(activity)
    }
    frameLayoutParams = mChildOfContent.layoutParams as FrameLayout.LayoutParams
}

private fun possiblyResizeChildOfContent(activity: Activity) {

    // 當前可視區域的高度
    val usableHeightNow = computeUsableHeight()
    // 當前高度值和之前的進行對比,變化將進行重繪
    if (usableHeightNow != usableHeightPrevious) {
        // 獲取當前螢幕高度
        // Ps:並不是真正的螢幕高度,是當前app的視窗高度,分屏時的高度為分屏視窗高度
        var usableHeightSansKeyboard = mChildOfContent.rootView.height
        // 高度差值:螢幕高度 - 可視內容高度
        var heightDifference = usableHeightSansKeyboard - usableHeightNow
        // 差值為負,說明獲取螢幕高度時出錯,寬高狀態值反了,重新計算
        if (heightDifference < 0) {
            usableHeightSansKeyboard = mChildOfContent.rootView.width
            heightDifference = usableHeightSansKeyboard - usableHeightNow
        }

        when {
            // keyboard probably just became visible
            // 如果差值大於螢幕高度的 1/4,則認為輸入軟鍵盤為彈出狀態
            heightDifference > usableHeightSansKeyboard / 4 ->
                // 設定佈局高度為:螢幕高度 - 高度差
                frameLayoutParams.height = usableHeightSansKeyboard - heightDifference

            // keyboard probably just became hidden
            // 虛擬導航欄顯示
            heightDifference >= getNavigationBarHeight(activity) ->
                frameLayoutParams.height = usableHeightSansKeyboard - getNavigationBarHeight(activity)

            // 其他情況直接設定為可視高度即可
            else -> frameLayoutParams.height = usableHeightNow
        }
    }

    // 重新整理佈局,會重新測量、繪製
    mChildOfContent.requestLayout()
    // 儲存高度資訊
    usableHeightPrevious = usableHeightNow

}

/**
 * 獲取可視內容區域的高度
 */
private fun computeUsableHeight(): Int {
    val r = Rect()
    // 當前視窗可視區域,不包括通知欄、導航欄、輸入鍵盤區域
    mChildOfContent.getWindowVisibleDisplayFrame(r)
    return if (isImmersed) {
        // 沉浸模式下,底部座標就是內容有效高度
        r.bottom
    } else {
        // 非沉浸模式下,去掉通知欄的高度 r.top(可用於通知欄高度的計算)
        r.bottom - r.top
    }
}

// 獲取導航欄真實的高度(可能未顯示)
private fun getNavigationBarHeight(context: Context): Int {
    var result = 0
    val resources = context.resources
    val resourceId =
        resources.getIdentifier("navigation_bar_height", "dimen", "android")
    if (resourceId > 0) {
        result = resources.getDimensionPixelSize(resourceId)
    }
    return result
}

} ```

使用方法

在有webView的Activity中執行下面程式碼

GlobalLayoutUtils(this,true);

"詳情"