天天看點

【Android問題及其解決】Android WebView 和 Soft keyboard 的顯示隐藏問題

問題描述:     業務要求,使用webView來展示網頁内容。在網頁中,有<input>标簽的輸入框,通過點選輸入框,彈出系統軟鍵盤進行輸入。但是無論是android 虛拟機還是實體機上,都無法第一時間彈出軟鍵盤。通過操作應用,反而發現将應用前背景進行切換一下,再切入前台展示webView,此時的軟鍵盤就能夠正常彈出。

    顯然這個問題中軟鍵盤的是否彈出與目前展示的view的焦點擷取息息相關。

    網上百度關鍵字之後,很多都是建議去強制擷取一下焦點,再用輸入框對象将輸入法強制彈出來。

setFocusable(true); setFocusableInTouchMode(true); requestFocus(View.FOCUS_DOWN);//與方法 requestFocus() 效果是一樣的

    問題中擷取焦點的視圖是一個 WebView ,無論是在布局中添加索取焦點的屬性,還是在代碼中添加上述代碼要求擷取一下焦點,在點選網頁輸入框都無法彈出軟鍵盤。通過在 StackOverFlow 上搜相關問題,搜尋到一個比較相關的 Tapping form field in WebView does not show soft keyboard   其中也是在于如何使得 WebView 擷取焦點的問題上,又多了如下代碼,加上之後仍然是沒有作用。

webview.setOnTouchListener(new View.OnTouchListener() {     @Override     public boolean onTouch(View v, MotionEvent event) {         switch (event.getAction()) {             case MotionEvent.ACTION_DOWN:             case MotionEvent.ACTION_UP:                 if (!v.hasFocus()) {                     v.requestFocus();                 }                 break;             }         return false;        } });

    接着又想到另一個辦法,就是在前端的 js 代碼中監聽 <input> 标簽的點選事件,通過 JSBridge 來通知用戶端強制彈出軟鍵盤,但是使用 WebView 當做參數調用 InputMethodManager 強制彈出鍵盤無法成功,原來傳入的參數 View 對象也是有要求的,原理如下。      系統中控制輸入法都是由 InputMethodManager 來進行互動的,而其中控制鍵盤顯示隐藏的方法根據參賽類型可以分為兩類,一類是通過傳入View當做參數,另一類是通過傳入 IBinder 類型的 windowToken 當做參數(通過 View.getWindowToken() 方法擷取)。其中 View 必須是可以接受輸入的視圖,什麼是可以接受輸入的視圖呢?在 View 中有這樣幾個方法。

//由  InputMethodManager 類來調用,用來檢查這個 View 類型對象是否是可以被當做接收輸入法輸入的視圖,預設傳回是 false public boolean checkInputConnectionProxy(View view){     return false; }

//傳回被調用者的這個 View 類型對象是否是一個文本輸入框類型的視圖,如果傳回是 true ,同時需要實作 onCreateInputConnection(EditorInfo outAttrs) 這個方法 public boolean onCheckIsTextEditor(){     return false; }

//允許擷取焦點且接受文本輸入的 View 類型對象需要實作,通過傳回 InputConnection 類型對象來與輸入法進行互動 public InputConnection onCreateInputConnection(EditorInfo outAttrs){     return null; }

    顯然 WebView 也不是一個可以接受文本輸入的對象,是以通過 JSBridge 的想法也走不通了。

    斷點的過程中,發現展示過程中的 WebView 觸摸監聽中,是一直處于擷取了焦點的狀态中,然後前背景一切換再回到應用,斷點顯示方法調用沒有不同的地方,那這個過程中唯一變化的就是 WebView 的焦點了,經曆了擷取焦點->失去焦點->擷取焦點的過程,那會不會就是由于焦點一直不變,才導緻了鍵盤彈不出來?之後,在進入 WebView ,網頁加載完成之後,快速彈了一個透明的對話框,然後快速消失,視覺上感受不到彈框,去搶占了一下焦點,焦點發生變化,此時再去點選網頁中的輸入框,軟鍵盤正常彈出了。

    既然解決了 WebView 中輸入框點選軟鍵盤無法彈出的問題,如果有需求要求不允許彈出系統的軟鍵盤或者隻能彈出自定義的某個鍵盤,那麼該如何處理?根據前面的可以接受輸入的視圖才能和鍵盤輸入法進行互動,那麼把這些“可以接受輸入的視圖”變成不可接受輸入的視圖,鍵盤自然就彈不出來了,即調用方法 setFocusable(false); 傳入 false 進去,再在相關 View 對象上添加點選或者觸摸的監聽,監聽中添加業務即可。