在DialogFragment中使用EditText,onDismiss时关闭键盘无效的问题

最近的项目要实现一个评论框,点击某处触发弹出软键盘,在软键盘上面显示EditText输入评论内容,还有2点需求

  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.view.inputmethod.InputMethodManager#hideSoftInputFromWindow(android.os.IBinder, int)最终会调用它的重载方法android.view.inputmethod.InputMethodManager#hideSoftInputFromWindow(android.os.IBinder, int, android.os.ResultReceiver)

    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呢?是在这里:

    /**
     * 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();
        }
    }

在这里定下断点,看看是怎么调用过来的呢?

在这里插入图片描述

这里看到了熟悉的android.app.Dialog#dismiss那么就是说在当前情况下,在dialog dismiss的时候mServedView就被置为null,但是这个时候上面的一些列监听方法都还没用被调用,解决方法呢就是在mServedView被置空前调用hideSoftInputFromWindow(),至此问题解决。

  override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val dialog = object :Dialog(activity!!, setStyle()){
            override fun dismiss() {
            	//关闭时机
                KeyboardUtils.hideSoftInput(activity!!,inputDlg!!)
                super.dismiss()
            }
        }

这个问题不难,但是还是稍微花了一点时间,意义就是遇到问题不一定要先多方搜索,可能自己花一点点时间看看内部,解决起来可能更快些。记录自勉,备查。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值