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

首頁 > 系統 > Android > 正文

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

2019-12-12 02:06:24
字體:
來源:轉載
供稿:網友

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)); } 

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 万安县| 涞源县| 华池县| 云和县| 满城县| 咸丰县| 台山市| 宁蒗| 安塞县| 保定市| 旬邑县| 甘肃省| 石台县| 大理市| 莲花县| 沙田区| 牡丹江市| 宁海县| 元氏县| 兴隆县| 洞头县| 电白县| 通道| 叶城县| 漠河县| 利辛县| 泰和县| 庄河市| 大宁县| 东乡| 渝中区| 白朗县| 南开区| 临武县| 潜山县| 尼木县| 宁武县| 达日县| 红桥区| 惠来县| 岳池县|