欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android?WebView軟鍵盤遮擋輸入框方案詳解

 更新時(shí)間:2022年06月07日 10:42:26   作者:guodongAndroid  
這篇文章主要介紹了Android?WebView軟鍵盤遮擋輸入框方案詳解,本文提供了一種新的解決?WebView?輸入框被軟鍵盤遮擋的思路,不過(guò)這種思路也有它的局限性,目前來(lái)看僅適用于全屏的?WebView?中,需要的朋友可以參考下

背景

筆者在使用 WebView 加載含有輸入框的 H5 頁(yè)面時(shí),點(diǎn)擊輸入框后,輸入框會(huì)被軟鍵盤遮擋住,無(wú)法看到輸入的內(nèi)容,這很影響用戶體驗(yàn)。

筆者想著這種業(yè)務(wù)場(chǎng)景比較常見,遂上網(wǎng)搜索一番,果不其然,有不少同志遇到這個(gè)問(wèn)題,想來(lái)這個(gè)問(wèn)題很好解決了。筆者一一嘗試了同志們提供的解決方案,結(jié)果要不是沒有作用,要不是效果不太滿意,只好自己另辟蹊徑了。

注:在筆者的業(yè)務(wù)場(chǎng)景中,App是全屏的,即沒有頂部的系統(tǒng)欄,也沒有底部的導(dǎo)航欄,所以筆者的解決方案,可能不適用于其他場(chǎng)景。

紀(jì)實(shí)

方案

好的,重新梳理下遇到的問(wèn)題,目前的問(wèn)題是:用戶無(wú)法看到輸入框里的內(nèi)容,那么我們可以先讓用戶看到輸入框里的內(nèi)容。

筆者想到了第一種方案:**輸入框被軟鍵盤遮擋后,在軟鍵盤輸入時(shí),可以在 H5 頁(yè)面頂部實(shí)時(shí)顯示輸入框里的內(nèi)容。**本方案解決了輸入框被軟鍵盤遮擋后看不到輸入內(nèi)容的問(wèn)題,但是沒有解決輸入框被軟鍵盤遮擋的問(wèn)題,此方案一定程度上提升了用戶體驗(yàn),不過(guò)筆者認(rèn)為本方案不是很完美,繼續(xù)思考其他方案。

最后筆者想到了第二種方案,大體思路如下:

  • 筆者的業(yè)務(wù)場(chǎng)景,App是全屏的,所以整個(gè) WebView 也是全屏的,
  • 在點(diǎn)擊 H5 頁(yè)面的輸入框時(shí),H5 獲取當(dāng)前輸入框左下角的 Y 坐標(biāo),然后把左下角的 Y 坐標(biāo)通知到 Android 原生,
  • Android 原生獲取軟鍵盤頂部的 Y 坐標(biāo)與輸入框左下角的 Y 坐標(biāo)進(jìn)行比較,如果小于左下角的 Y 坐標(biāo),則認(rèn)為此時(shí)輸入框被軟鍵盤遮擋,需要將 WebView 向上滾動(dòng)相應(yīng)的距離以顯示出來(lái)輸入框,否則判斷 WebView 當(dāng)前的滾動(dòng)距離是否為 0,如果不為 0 則取當(dāng)前距離的負(fù)值作為滾動(dòng)距離,否則就不滾動(dòng)。

上述方案的文字描述可能比較繞,我們可以看下面的流程圖跟上思路:

實(shí)現(xiàn)

接下來(lái)筆者根據(jù)上面的方案二進(jìn)行代碼上的具體實(shí)現(xiàn):

首先是獲取輸入框左下角的 Y 坐標(biāo),這一步如果讓前端來(lái)實(shí)現(xiàn)的話,是比較容易的,不過(guò)筆者認(rèn)為方案二是一種比較通用的解決方案,可以提取出來(lái)作為二方庫(kù)來(lái)使用,如果讓其他使用二方庫(kù)項(xiàng)目組的前端同志也來(lái)實(shí)現(xiàn)一次的話就比較麻煩了,所以在這一步,筆者選擇了在 Android 端注入 JS 的方案:

ready();
document.addEventListener("readystatechange", function () {
    var readyState = document.readyState;
    if (readyState !== "loading") {
        console.log(readyState);
        ready();
    }
});
document.addEventListener("DOMContentLoaded", function () {
    console.log("DOMContentLoaded");
    ready();
});
function ready() {
    document.body.addEventListener("DOMNodeInserted", function () {
        webInput();
    });
    webInput();
}
function webInput() {
    var input = document.querySelectorAll("input") || [];
    console.log("input -> " + input.length);
    if (input.length === 0) {
        return;
    }
    input.forEach(function (value) {
        var type = value.getAttribute("type");
        console.log("type -> " + type);
        if (type === null
            || type === "number"
            || type === "search"
            || type === "password"
            || type === "tel"
            || type === "email"
            || type === "url"
            || type === "text") {
            value.removeEventListener("click", webInput2Android);
            value.removeEventListener("focus", webInput2Android);
            value.addEventListener("click", webInput2Android);
            value.addEventListener("focus", webInput2Android);
        }
    });
}
function webInput2Android() {
    console.log("webInput2Android");
    var offset = getOffset(this);
    var x = offset.x;
    var y = offset.y;
    console.log("x:y --> " + x + ":" + y);
    var width = this.offsetWidth;
    var height = this.offsetHeight;
    console.log("w:h --> " + width + ":" + height);
	// Send to Android
}
function getOffset (el) {
    var box = el.getBoundingClientRect();
    return {
        x: box.left + window.pageXOffset - document.documentElement.clientLeft,
        y: box.top + window.pageYOffset - document.documentElement.clientTop
    }
}

在 JS 中通過(guò)監(jiān)聽輸入框的點(diǎn)擊事件,在點(diǎn)擊時(shí)獲取輸入框左上角的坐標(biāo)和輸入框的寬高,間接算出輸入框左下角的坐標(biāo),然后通知到 Android 原生:

public void run() {
    Activity activity = mActivityReference.get();
    WebView webView = mWebViewReference.get();
    if (activity == null || webView == null) {
        return;
    }
    // JS 傳入的輸入框左下角 Y 坐標(biāo)
    int bottom = mWebInput.getBottom();
    // 獲取軟鍵盤頂部的 Y 坐標(biāo)
    int keyboardTop = KeyboardHelper.getKeyboardTop(activity);
    // WebView 當(dāng)前滾動(dòng)的距離
    int scrollY = webView.getScrollY();
    // 判斷軟鍵盤是否彈出
    if (keyboardTop != -1) {
        // 判斷輸入框是否被軟鍵盤遮擋
        if (bottom >= keyboardTop) {
            // 計(jì)算滾動(dòng)距離
            int diff = bottom - keyboardTop - scrollY;
            // 滾動(dòng) WebView diff + mDistance 距離,mDistance 默認(rèn) 50,
            // diff + mDistance:即軟鍵盤距離輸入框底部 50 距離 
            webView.assistWebKeyboard(scrollY, diff + mDistance);
        } else {
            // 判斷 WebView 是否有滾動(dòng)
            if (scrollY != 0) {
                // 滾動(dòng) WebView
                webView.assistWebKeyboard(scrollY, -scrollY);
            }
        }
    }
}

以上代碼實(shí)現(xiàn)方案二中第三步,首先獲取 JS 傳入的輸入框左下角 Y 坐標(biāo),其次獲取軟鍵盤頂部的 Y 坐標(biāo),然后獲取 WebView 當(dāng)前滾動(dòng)的距離,接下來(lái)根據(jù)軟鍵盤頂部的 Y 坐標(biāo)判斷軟鍵盤是否彈出,在軟鍵盤彈出的情況下,判斷輸入框左下角 Y 坐標(biāo)是否大于等于軟鍵盤頂部 Y 坐標(biāo):

  • 如果大于等于,則認(rèn)為輸入框被軟鍵盤遮擋,此時(shí)計(jì)算出 WebView 需要滾動(dòng)多長(zhǎng)的距離,輸入框才能被顯示出來(lái),最后調(diào)用 assistWebKeyboard 方法滾動(dòng) WebView
  • 如果小于,則認(rèn)為輸入框沒有被軟鍵盤遮擋,此時(shí)判定 WebView 之前是否有滾動(dòng),如果有滾動(dòng)距離,則計(jì)算滾動(dòng)距離為當(dāng)前滾動(dòng)距離的負(fù)值,最后調(diào)用 assistWebKeyboard 方法滾動(dòng) WebView

至此完結(jié)。

總結(jié)

本文提供了一種新的解決 WebView 輸入框被軟鍵盤遮擋的思路,不過(guò)這種思路也有它的局限性,目前來(lái)看僅適用于全屏的 WebView 中,后續(xù)筆者再想到其他方案時(shí),另寫一篇紀(jì)實(shí)續(xù)集吧。

到此這篇關(guān)于Android WebView軟鍵盤遮擋輸入框方案詳解的文章就介紹到這了,更多相關(guān)android 軟鍵盤遮擋輸入框內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論