国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android 開發之Dialog中隱藏鍵盤的正確使用方法

2019-10-22 18:28:37
字體:
來源:轉載
供稿:網友

Android 開發之Dialog中隱藏鍵盤的正確使用方法

場景:彈出一個Dialog,里面有一個EditText,用來輸入內容,因為輸入時,需要彈出鍵盤,所以當Dialog消失時,鍵盤要一起隱藏。

現在我們做一個自定義的Dialog

MyDialog extends Dialog 

一開始認為這個功能很容易實現,于是寫了下面的代碼

//Dialog的構造函數中寫   this.setOnDismissListener(new OnDismissListener() {    @Override    public void onDismiss(DialogInterface dialog) {     hideKeyBoard();    }   }); //edContent是輸入框  public void hideKeyBoard(){   InputMethodManager inputMethodManager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);   inputMethodManager.hideSoftInputFromWindow(edContent.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);  } 

運行之后,發現根本無法隱藏,看看hideSoftInputFromWindow中干了啥

public boolean hideSoftInputFromWindow(IBinder windowToken, int flags,     ResultReceiver resultReceiver) {   checkFocus();   synchronized (mH) {     if (mServedView == null || mServedView.getWindowToken() != windowToken) {       return false;     }      try {       return mService.hideSoftInput(mClient, flags, resultReceiver);     } catch (RemoteException e) {     }     return false;   } } 

跟蹤進去發現參數 windowToken 是 null,而且 mServedView 也是null,所以直接返回false,無法隱藏。

也就是說,你監聽Cancel或者Dismiss都是不行的,因為此時Dialog已經消失,用于輸入的服務窗體已經是null了,所以你要想 隱藏鍵盤,就需要在Dismiss之前處理,那這個入口在哪呢?

為了當點擊空白處時,可以隱藏Dialog,所以我們在構造函數中加了一句話

this.setCanceledOnTouchOutside(true); 

所以當我們點擊空白區域時,會觸發Dialog的onTouchEvent

public boolean onTouchEvent(MotionEvent event) {   if (mCancelable && mShowing && mWindow.shouldCloseOnTouch(mContext, event)) {     cancel();     return true;   }      return false; } 

這里會調用基類Window的shouldCloseOnTouch方法,來判斷是否可以關閉,這里我們看到如果滿足,就直接cancel()了,

public void cancel() {   if (!mCanceled && mCancelMessage != null) {     mCanceled = true;     // Obtain a new message so this dialog can be re-used     Message.obtain(mCancelMessage).sendToTarget();   }   dismiss(); } 

這里面就會dismiss掉Dialog,所以我們發現,在dismiss前,我們根本無法干預,真是個悲劇。所以我們只能重載onTouchEvent方法,并且自己判斷是否可以關閉(也就是把下面代碼遷移到你的代碼中!

public boolean shouldCloseOnTouch(Context context, MotionEvent event) {   if (mCloseOnTouchOutside && event.getAction() == MotionEvent.ACTION_DOWN       && isOutOfBounds(context, event) && peekDecorView() != null) {     return true;   }   return false; }  private boolean isOutOfBounds(Context context, MotionEvent event) {   final int x = (int) event.getX();   final int y = (int) event.getY();   final int slop = ViewConfiguration.get(context).getScaledWindowTouchSlop();   final View decorView = getDecorView();   return (x < -slop) || (y < -slop)       || (x > (decorView.getWidth()+slop))       || (y > (decorView.getHeight()+slop)); } 

自己代碼中這樣

@Override public boolean onTouchEvent(MotionEvent event) {  if (isShowing() && shouldCloseOnTouch(getContext(),event)){   hideKeyBoard();  }  return super.onTouchEvent(event); } public boolean shouldCloseOnTouch(Context context, MotionEvent event) {  if (event.getAction() == MotionEvent.ACTION_DOWN      && isOutOfBounds(context, event) && getWindow().peekDecorView() != null) {   return true;  }  return false; } private boolean isOutOfBounds(Context context, MotionEvent event) {  final int x = (int) event.getX();  final int y = (int) event.getY();  final int slop = ViewConfiguration.get(context).getScaledWindowTouchSlop();  final View decorView = getWindow().getDecorView();  return (x < -slop) || (y < -slop)      || (x > (decorView.getWidth()+slop))      || (y > (decorView.getHeight()+slop)); } 

如有疑問請留言或者到本站社區交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 桑日县| 洪雅县| 长沙县| 黔西| 龙海市| 桂东县| 金湖县| 松潘县| 金华市| 社旗县| 镇赉县| 林口县| 青河县| 阳江市| 深州市| 岢岚县| 阳新县| 建水县| 莱阳市| 庆阳市| 宣威市| 勃利县| 文化| 忻城县| 阿克陶县| 高陵县| 景谷| 永昌县| 正定县| 高淳县| 乐陵市| 察隅县| 宝坻区| 巴彦县| 滦平县| 自治县| 阳东县| 方山县| 通化县| 防城港市| 娄底市|