在DialogFragment中使用EditText,onDismiss時關閉鍵盤無效的問題

最近的項目要實現一個評論框,點擊某處觸發彈出軟鍵盤,在軟鍵盤上面顯示EditText輸入評論內容,還有2點需求java

  1. 點擊空白處關閉輸入框並收起軟鍵盤。
  2. 發送完評論後也關閉輸入框並收起軟鍵盤。

在使用DialogFragment中建立Dialog實現了評論框後,2能夠正常實現,可是1存在輸入框關閉了可是軟鍵盤沒有收起的狀況。開始覺得問題在android.view.inputmethod.InputMethodManager#hideSoftInputFromWindow(android.os.IBinder, int)的調用傳參上面,按照網上的方法,各類修改傳入的windowToken和flag均無效。後續也在android.support.v4.app.DialogFragment#dismissandroid.support.v4.app.DialogFragment#onDismissandroid.app.Dialog#setOnDismissListener中調用hideSoftInputFromWindow()均無效,沒有辦法只有斷點跟進代碼執行流程一探究竟。android

android.view.inputmethod.InputMethodManager#hideSoftInputFromWindow(android.os.IBinder, int)最終會調用它的重載方法android.view.inputmethod.InputMethodManager#hideSoftInputFromWindow(android.os.IBinder, int, android.os.ResultReceiver)web

public boolean hideSoftInputFromWindow(IBinder windowToken, int flags,
            ResultReceiver resultReceiver) {
        checkFocus();
        synchronized (mH) {
           //個人主動調用運行到這裏的時候,mServedView爲null,因此並無調用到後續的Binder通訊代碼。鍵盤天然不會收起了
            if (mServedView == null || mServedView.getWindowToken() != windowToken) {
                return false;
            }
            try {
                return mService.hideSoftInput(mClient, flags, resultReceiver);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
    }

在正常狀況下mServedView是不爲null的,那麼mServedView是在哪裏被賦值爲null呢?是在這裏:app

/** * Disconnect any existing input connection, clearing the served view. */
    void finishInputLocked() {
        mNextServedView = null;
        if (mServedView != null) {
            if (DEBUG) Log.v(TAG, "FINISH INPUT: mServedView=" + dumpViewInfo(mServedView));
            if (mCurrentTextBoxAttribute != null) {
                try {
                    mService.finishInput(mClient);
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
            }
            mServedView = null; //看這裏
            mCompletions = null;
            mServedConnecting = false;
            clearConnectionLocked();
        }
    }

在這裏定下斷點,看看是怎麼調用過來的呢?ide

在這裏插入圖片描述

這裏看到了熟悉的android.app.Dialog#dismiss那麼就是說在當前狀況下,在dialog dismiss的時候mServedView就被置爲null,可是這個時候上面的一些列監聽方法都還沒用被調用,解決方法呢就是在mServedView被置空前調用hideSoftInputFromWindow(),至此問題解決。svg

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val dialog = object :Dialog(activity!!, setStyle()){
            override fun dismiss() {
            	//關閉時機
                KeyboardUtils.hideSoftInput(activity!!,inputDlg!!)
                super.dismiss()
            }
        }

這個問題不難,可是仍是稍微花了一點時間,意義就是遇到問題不必定要先多方搜索,可能本身花一點點時間看看內部,解決起來可能更快些。記錄自勉,備查。spa