十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
为了实现键盘的监控,从新开发一个输入法是不现实的,一般的操作就是在系统的输入法机制中添加接口回调。我们知道,再应用程序中拿到按键的回调一般是监听onKeyDown的接口,如下所示:publicbooleanonKeyDown(intkeyCode,KeyEventevent)开发者就可以根据回调方法中的参数,keyCode与KeyEvent来判断具体事件。但是,由于事件的回调机制在其的沙箱中运行,在其他应用中是无法拿到当前应用事件回调的。那么我们就从上到下,具体的看看事件的传递机制。如下图所示,用户点击后,软键盘或物理按键的输入驱动就会产生一个中断,且向/dev/input/event*中写入一个相应的信号量。Android操作系统则会循环的读取其中的事件,再分发给WindowManagerServer。由WindowManagerServer根据事件的来源分发到各个不同的ViewGroup与View中,从而产生不同的OnClick、OnKeyDown和OnTouch等事件。这个时候很自然的想到,黑客们希望做键盘监控,一定会向Linux底层增加自定义的事件。这里我们使用的是Linux中的getevent获得/dev/input/eventX设备汇报的事件,这个命令还会输出所有event设备的基本信息。包括触屏、按键、耳机插入等等。其基本用法如下:Usage:getevent[-t][-n][-sswitchmask][-S][-v[mask]][-d][-p][-i][-l][-q][-ccount][-r][device]-t:showtimestamps-n:don'tprintnewlines-s:printswitchstatesforgivenbits-S:printallswitchstates-v:verbositymask(errs=1,dev=2,name=4,info=8,vers=16,pos.events=32,props=64)-d:showHIDdescriptor,ifavailable-p:showpossibleevents(errs,dev,name,pos.events)-i:showalldeviceinfoandpossibleevents-l:labeleventtypesandnamesinplaintext-q:quiet(clearverbositymask)-c:printgivennumberofeventsthenexit-r:printrateeventsarereceived键入getevent后,我们能够看到设备中的一些列输入硬件驱动信息,同样下面会出现很多输入指令信号,通常情况下,这些信号量都在刷屏,如下图所示:这些信号量的表示我们无法直接看懂,输入getevent–l加入Label我们能够看到一些添加的标签,如下所示:其实这些Lable已经在其input.h头文件中定义好,其中type的定义如下:/**Eventtypes*/#defineEV_SYN0x00#defineEV_KEY0x01#defineEV_REL0x02#defineEV_ABS0x03#defineEV_MSC0x04#defineEV_SW0x05#defineEV_LED0x11#defineEV_SND0x12#defineEV_REP0x14#defineEV_FF0x15#defineEV_PWR0x16#defineEV_FF_STATUS0x17#defineEV_MAX0x1f#defineEV_CNT(EV_MAX+1)一般来说,常用的是EV_KEY、EV_REL、EV_ABS、EV_SYN,分别对应键盘按键、相对坐标、绝对坐标、同步事件。EV_SYN则表示一组完整事件已经完成,需要处理,EV_SYN的code定义事件分发的类型。
在长顺等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供成都做网站、网站建设 网站设计制作按需策划设计,公司网站建设,企业网站建设,品牌网站制作,全网整合营销推广,外贸网站建设,长顺网站建设费用合理。
原理:自定义布局的onSizeChanged()方法,在其中增加一个监听接口,当软键盘显示或隐藏使得布局尺寸发生改变,就能捕获到这个事件。
具体方法如下:
首先,在清单文件Manifest.xml中的对应的Activity标签内设置
android:windowSoftInputMode=”adjustResize”
作用是当软键盘显示或隐藏时,该Activity主窗口总是会被调整大小以便留出软键盘的空间。唯有这样才能保证布局触发onSizeChanged()方法。
然后,自定义一个布局,具体是RelativeLayout、LinearLayout或是其它的,根据实际情况而定,自定义的目的是在其onSizeChanged()方法中增加一个监听接口。这里给出一个自定义RelativeLayout布局代码:
public class CustomRelativeLayout extends RelativeLayout {
private OnSizeChangedListener listener;
public CustomRelativeLayout(Context context) {
super(context);
}
public CustomRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
Log.d(TAG.CUSTOM_VIEW, “onSizeChanged”);
super.onSizeChanged(w, h, oldw, oldh);
if (listener != null) {
listener.onSizeChanged(w, h, oldw, oldh);
}
}
public void setOnSizeChangedListener(OnSizeChangedListener listener) {
this.listener = listener;
}
/** * Activity主窗口大小改变时的回调接口(本示例中,等价于软键盘显示隐藏时的回调接口) */
public interface OnSizeChangedListener {
public void onSizeChanged(int w, int h, int oldw, int oldh);
}
}
最后,在程序中使用此接口(xxx.setOnSizeChangedListener(…))即可实现监听键盘隐藏或显示事件。
我们在android手机上面有时候会遇到监听手机软键盘按键的时候,例如:我们在浏览器输入url完毕后可以点击软键盘右下角的“GO”按键加载url页面;在点击搜索框的时候,点击右下角的search符号键可以进行搜索;或者在全部数据输入完毕后,点击右下角的"done"就马上进行下一步操作。
function 1:
重写Activity的dispatchKeyEvent(KeyEvent event)方法,在其中监听KeyEventKey.KEYCODE_ENTER键(右下角确定键),当此键按下的时候,隐藏输入法软键盘,设置edittext内容和加载webview内容。
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if(event.getKeyCode() == KeyEvent.KEYCODE_ENTER){
/*隐藏软键盘*/
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if(inputMethodManager.isActive()){
inputMethodManager.hideSoftInputFromWindow(MainActivity.this.getCurrentFocus().getWindowToken(), 0);
edittext.setText("success");
webview.loadUrl(URL);
return true;
return super.dispatchKeyEvent(event);
}
function 2:
重写dispatchKeyEvent(KeyEvent event)的方法感觉有点用牛刀的感觉,因为我们非常可能在这个方法中进行其他任务,所以我们可以使用OnKeyListener的方法来监听软键盘按键。
private OnKeyListener onKeyListener = new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_ENTER){
/*隐藏软键盘*/
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if(inputMethodManager.isActive()){
inputMethodManager.hideSoftInputFromWindow(v.getApplicationWindowToken(), 0);
edittext.setText("success");
webview.loadUrl(URL);
return true;
return false;
};
edittext.setOnKeyListener(onKeyListener);
function 3:
第三种方法我认为可以帮助程序员更精确的判断右下角按键情况,以便应对更加复杂的情况。它可以帮助程序员依据当前邮件下为“GO”,“done”,“search”键的情况下做出更细分的操作。
edittext.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
/*判断是否是“GO”键*/
if(actionId == EditorInfo.IME_ACTION_GO){
/*隐藏软键盘*/
InputMethodManager imm = (InputMethodManager) v
.getContext().getSystemService(
Context.INPUT_METHOD_SERVICE);
if (imm.isActive()) {
imm.hideSoftInputFromWindow(
v.getApplicationWindowToken(), 0);
edittext.setText("success");
webview.loadUrl(URL);
return true;
return false;
});
总结:
1.在ios中软键盘弹起时,仅会引起body的scrollTop值改变,但是我们可以通过输入框的获取焦点情况来做判断,单也只能在ios中采用这个方案,因为在android中存在主动受气键盘后,但输入框并没有失去焦点,而ios中键盘受气后就会失去焦点;
2.在androis中软键盘弹起或收起时,会改变window的高度,因此监听window的onresize事件;
一、Android
//获取原窗口的高度
var originalHeight=document.documentElement.clientHeight ||document.body.clientHeight;
window.onresize=function(){
//键盘弹起与隐藏都会引起窗口的高度发生变化
var resizeHeight=document.documentElement.clientHeight || document.body.clientHeight;
if(resizeHeight-0originalHeight-0){
//当软键盘弹起,在此处操作
}else{
//当软键盘收起,在此处操作
}
}
二、ios
focusin和focusout支持冒泡,对应focus和blur, 使用focusin和focusout的原因是focusin和focusout可以冒泡,focus和blur不会冒泡,这样就可以使用事件代理,处理多个输入框存在的情况。
document.body.addEventListener('focusin', () = {
//软键盘弹出的事件处理
if(isIphone()){
}
})
document.body.addEventListener('focusout', () = {
//软键盘收起的事件处理
if(isIphone()){
}
})
特此声明文章出处: