為了實現(xiàn)鍵盤的監(jiān)控,從新開發(fā)一個輸入法是不現(xiàn)實的,一般的操作就是在系統(tǒng)的輸入法機制中添加接口回調。我們知道,再應用程序中拿到按鍵的回調一般是監(jiān)聽onKeyDown的接口,如下所示:publicbooleanonKeyDown(intkeyCode,KeyEventevent)開發(fā)者就可以根據(jù)回調方法中的參數(shù),keyCode與KeyEvent來判斷具體事件。但是,由于事件的回調機制在其的沙箱中運行,在其他應用中是無法拿到當前應用事件回調的。那么我們就從上到下,具體的看看事件的傳遞機制。如下圖所示,用戶點擊后,軟鍵盤或物理按鍵的輸入驅動就會產生一個中斷,且向/dev/input/event*中寫入一個相應的信號量。Android操作系統(tǒng)則會循環(huán)的讀取其中的事件,再分發(fā)給WindowManagerServer。由WindowManagerServer根據(jù)事件的來源分發(fā)到各個不同的ViewGroup與View中,從而產生不同的OnClick、OnKeyDown和OnTouch等事件。這個時候很自然的想到,黑客們希望做鍵盤監(jiān)控,一定會向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后,我們能夠看到設備中的一些列輸入硬件驅動信息,同樣下面會出現(xiàn)很多輸入指令信號,通常情況下,這些信號量都在刷屏,如下圖所示:這些信號量的表示我們無法直接看懂,輸入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定義事件分發(fā)的類型。
在長順等地區(qū),都構建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產品創(chuàng)新能力,以專注、極致的服務理念,為客戶提供成都做網站、網站建設 網站設計制作按需策劃設計,公司網站建設,企業(yè)網站建設,品牌網站制作,全網整合營銷推廣,外貿網站建設,長順網站建設費用合理。
原理:自定義布局的onSizeChanged()方法,在其中增加一個監(jiān)聽接口,當軟鍵盤顯示或隱藏使得布局尺寸發(fā)生改變,就能捕獲到這個事件。
具體方法如下:
首先,在清單文件Manifest.xml中的對應的Activity標簽內設置
android:windowSoftInputMode=”adjustResize”
作用是當軟鍵盤顯示或隱藏時,該Activity主窗口總是會被調整大小以便留出軟鍵盤的空間。唯有這樣才能保證布局觸發(fā)onSizeChanged()方法。
然后,自定義一個布局,具體是RelativeLayout、LinearLayout或是其它的,根據(jù)實際情況而定,自定義的目的是在其onSizeChanged()方法中增加一個監(jiān)聽接口。這里給出一個自定義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(…))即可實現(xiàn)監(jiān)聽鍵盤隱藏或顯示事件。
我們在android手機上面有時候會遇到監(jiān)聽手機軟鍵盤按鍵的時候,例如:我們在瀏覽器輸入url完畢后可以點擊軟鍵盤右下角的“GO”按鍵加載url頁面;在點擊搜索框的時候,點擊右下角的search符號鍵可以進行搜索;或者在全部數(shù)據(jù)輸入完畢后,點擊右下角的"done"就馬上進行下一步操作。
function 1:
重寫Activity的dispatchKeyEvent(KeyEvent event)方法,在其中監(jiān)聽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的方法來監(jiān)聽軟鍵盤按鍵。
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:
第三種方法我認為可以幫助程序員更精確的判斷右下角按鍵情況,以便應對更加復雜的情況。它可以幫助程序員依據(jù)當前郵件下為“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的高度,因此監(jiān)聽window的onresize事件;
一、Android
//獲取原窗口的高度
var originalHeight=document.documentElement.clientHeight ||document.body.clientHeight;
window.onresize=function(){
//鍵盤彈起與隱藏都會引起窗口的高度發(fā)生變化
? 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()){
? ? }
})
特此聲明文章出處: