300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > android webview软键盘监听删除键 回车键 其他键

android webview软键盘监听删除键 回车键 其他键

时间:2019-12-27 10:54:36

相关推荐

android webview软键盘监听删除键 回车键 其他键

android webview软键盘监听删除键、回车键、其他键

终于有时间来写文章了,头一回发表,文章连贯性可能无法保障,大家勉强看一下吧

今天说点关于android 和 webview 沟通的时候,需要监听软键盘的按键事件的问题

情境描述:由于js在部分手机上(比如华为青春版P8)无法监听到删除键,引起项目部分功能无法实现

解决思路:js 与android 互相沟通 就不多说了,网上一搜一大片,重点说一下 我的解决办法,之前在网上搜了一下,说的是andriod跟webview交互的时候,就把输入法管理 权交给webview了,从自己的界面代码是没有办法去监听软键盘的,所以想到了,看能不能去拦截下 输入链接桥梁,然后再拦截事件转交给 js,这样那些js无法监听软键盘的事件就ok了,

6.0手机以上 你可以采用像网上说的,自定义Webview,继承Webview,自定义里面的其他覆写方法不多说,网上一搜一大片,重点是复写onCreateInputConnection(EditorInfo outAttrs)方法,返回一个InputConnection输入法链接桥梁,然后对这个输入法链接桥梁 做一些你要干的事情,代码如下:

public InputConnection onCreateInputConnection(EditorInfo outAttrs) { return new MyInputConnection(super.onCreateInputConnection(outAttrs),//用父类的输入链接桥梁 转换成自己的,以便于对输入事件拦截, true,onItemClickCallBackI); //onItemClickCallBackI是自定义的一个回调接口,没什么可说的

}

public InputConnection onCreateInputConnection(EditorInfo outAttrs) { return new MyInputConnection(super.onCreateInputConnection(outAttrs),//用父类的输入链接桥梁 转换成自己的,以便于对输入事件拦截, true,onItemClickCallBackI); //onItemClickCallBackI是自定义的一个回调接口,没什么可说的

}

public class MyInputConnection extends InputConnectionWrapper {private OnItemClickCallBackI onItemClickCallBackI; public MyInputConnection(InputConnection target, boolean mutable,OnItemClickCallBackI onCallBackI) {super(target, mutable);if(onCallBackI!=null){this.onItemClickCallBackI=onCallBackI;}}@Override public Handler getHandler() {return new Handler(); }@Override public boolean sendKeyEvent(KeyEvent event) {if(this.onItemClickCallBackI!=null){onItemClickCallBackI.callFirstBack(event);//按键事件回调}return super.sendKeyEvent(event); }@Override public boolean deleteSurroundingText(int beforeLength, int afterLength) {// magic: in latest Android, deleteSurroundingText(1, 0) will be called for backspaceif (beforeLength == 1 && afterLength == 0) {// backspace return sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL))&& sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL));}return super.deleteSurroundingText(beforeLength, afterLength); }}

super.onCreateInputConnection(outAttrs) 华为青春版P8这个方法直接就返回空了,根本无法拦截

这就尴尬了,也一直在去搜索这方面知识,奈何时间又短,项目又紧张,根本没有时间去看系统代码,所以只能想其他办法,后面看到了EditText是如何拦截输入内容的,然后觉得如果将整个webview假设成为EditText有没有可能,没想到一试,还真行,代码如下:

@Overridepublic InputConnection onCreateInputConnection(EditorInfo outAttrs) {super.onCreateInputConnection(outAttrs); return new MyInputConnection(new InputView(MyWebView.this,false,onItemTextClickCallBackI), true,onItemClickCallBackI);//InputView自己定义的继承基础输入链接桥梁类,}public class InputView extends BaseInputConnection {private OnItemClickCallBackI onItemTextClickCallBackI; public InputView(View targetView, boolean fullEditor,OnItemClickCallBackI textClickCallBackI) {super(targetView, fullEditor);this.onItemTextClickCallBackI=textClickCallBackI; }@Override public boolean commitText(CharSequence text, int newCursorPosition) {//System.out.println("截获的文字 :"+text);onItemTextClickCallBackI.callFirstBack(text);//文字拦截回调return true; }}public class MyInputConnection extends InputConnectionWrapper {private OnItemClickCallBackI onItemClickCallBackI; public MyInputConnection(InputConnection target, boolean mutable,OnItemClickCallBackI onCallBackI) {super(target, mutable);if(onCallBackI!=null){this.onItemClickCallBackI=onCallBackI;}}@Override public Handler getHandler() {return new Handler(); }@Override public boolean sendKeyEvent(KeyEvent event) {if(this.onItemClickCallBackI!=null){onItemClickCallBackI.callFirstBack(event);//事件拦截回调}return super.sendKeyEvent(event); }@Override public boolean deleteSurroundingText(int beforeLength, int afterLength) {// magic: in latest Android, deleteSurroundingText(1, 0) will be called for backspaceif (beforeLength == 1 && afterLength == 0) {// backspace return sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL))&& sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL));}return super.deleteSurroundingText(beforeLength, afterLength); }}

为什么去写了两个回调方法,一个是回调输入的文字,一个是回调软键盘的事件,当你去看到EditText 写拦截事件的时候,也没有整这么多内部类,原因就是以为webview毕竟不是EditView,不这么搞,要出事,

MyInputConnection 主要是去拦截软键盘的事件,

InputView 主要是去拦截输入的内容,

可能你只需要拦截软键盘事件,拦截内容干什么,接下来,你就明白了,

由于webview毕竟不是EditView,而且又是自定义的输入桥梁,当你在6.0以上系统是没有问题的,可是等到了6.0以下包括6.0,你会发现,你拦截的这个输入桥梁,根本无法输入汉字,英文 又是完全正常,这就尴尬了,好比以上的代码都是白费,其实不然,换个思路补救一下就OK,这就是为什么会有

InputView 这个类里面的 onItemTextClickCallBackI.callFirstBack(text);方法回调了

在回调的时候,将你拦截到的内容,传给js,让JS动态把这些字设到相应的控件上

这样中文 英文 都没有问题了,当然了,如果你有时间,可以去研究下系统源码,会有更好的处理中文和英文的办法

总的来说,解决办法就是 重新搭建 android 与webview的输入链接桥梁,拦截输入事件和内容,回调给js,这样在目前我实测了大量的手机下是没有问题的,

希望以上内容对您有所帮助,如果有更好的办法,还请指点

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。