【Android问题及其解决】Android WebView 和 Soft keyboard 的显示隐藏问题

问题描述:
    业务要求,使用webView来展示网页内容。在网页中,有标签的输入框,通过点击输入框,弹出系统软键盘进行输入。但是无论是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 代码中监听 标签的点击事件,通过 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 对象上添加点击或者触摸的监听,监听中添加业务即可。

你可能感兴趣的:(android其他)