目录

  • 弹出和关闭软键盘
  • 在DialogFragment显示时弹出软键盘
  • 在DialogFragment消失时关闭软键盘
    • 1.用户手动调用DialogFragment.dismiss()
    • 2.用户点击空白处关闭dialog
      • 重写onDismiss(dialog: DialogInterface)
      • 自定义Dialog在dismiss之前通知 DialogFragment 关闭软键盘

弹出和关闭软键盘

  • 弹出软键盘
    private val imm: InputMethodManager? by lazy { activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager? }private fun showSoftInput() {imm?.let {binding.apply {etChat.requestFocus()it.showSoftInput(etChat, InputMethodManager.SHOW_FORCED)}}}
  • 关闭软键盘
    private fun hideSoftInput() {imm?.hideSoftInputFromWindow(binding.etChat.windowToken, 0)}

在DialogFragment显示时弹出软键盘

在DialogFragment显示时有两种方式弹出软键盘:

1、在onViewCreated中发送一个延时任务

   etChat.postDelayed({ showSoftInput() }, 200)

注意:如果直接调用显示键盘不会起作用,因为这个时候view没有显示出来

2、设置dialog的style属性 android:windowSoftInputMode

    <style name="live_editTextDialogStyle" parent="@android:style/Theme.Dialog"><!-- 背景透明 --><item name="android:windowBackground">@android:color/transparent</item><item name="android:windowContentOverlay">@null</item><!-- 浮于Activity之上 --><item name="android:windowIsFloating">true</item><!-- 边框 --><item name="android:windowFrame">@null</item><!-- Dialog以外的区域模糊效果 --><item name="android:backgroundDimEnabled">false</item><!-- 无标题 --><item name="android:windowNoTitle">true</item><!-- 半透明 --><item name="android:windowIsTranslucent">true</item><!-- 显示软键盘 --><item name="android:windowSoftInputMode">stateAlwaysVisible</item></style>

在DialogFragment消失时关闭软键盘

dialog关闭分为几种情况,处理方式不一样:

1.用户手动调用DialogFragment.dismiss()

这时可以重写dismiss方法,在调用之前关闭软键盘。

    override fun dismiss() {hideSoftInput()super.dismiss()}

2.用户点击空白处关闭dialog

DialogFragment本身没有监听关闭之前的方法,只有两个相关方法onCancel(dialog: DialogInterface)和onDismiss(dialog: DialogInterface)

重写onCancel(dialog: DialogInterface)

    override fun onCancel(dialog: DialogInterface) {hideSoftInput()super.onCancel(dialog)}

当这样处理时发现软键盘没有关闭,可以看下流程:
看看InputMethodManager的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) {throw e.rethrowFromSystemServer();}}}

可以看到关闭软键盘的代码为mService.hideSoftInput
断点发现当在onCancel中关闭软键盘时 mServedView为null,所以走不到关闭代码,看一下mServedView在哪赋值为null的

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

finishInputLocked调用有两处地方

 private boolean checkFocusNoStartInput(boolean forceNewFocus) {// 已省略其余代码if (mNextServedView == null) {finishInputLocked();// 此方法会调用 mService.hideSoftInput,所以可以排除closeCurrentInput();return false;}return true;}public void windowDismissed(IBinder appWindowToken) {checkFocus();synchronized (mH) {if (mServedView != null &&mServedView.getWindowToken() == appWindowToken) {finishInputLocked();}}}

所以可以判断当回调到onCancel的时候,windowDismissed方法已经调用,所以无法关闭软键盘。此方式排除,再来看看onDismiss方法

重写onDismiss(dialog: DialogInterface)

    override fun onDismiss(dialog: DialogInterface) {hideSoftInput()super.onDismiss(dialog)}

在onDismiss调用时发现 hideSoftInputFromWindow()中的 mServedView不为null,但是 windowToken == null,看一下这个参数的获取

imm?.hideSoftInputFromWindow(binding.etChat.windowToken, 0)
// View.java ->public IBinder getWindowToken() {return mAttachInfo != null ? mAttachInfo.mWindowToken : null;}

mAttachInfo会在 dispatchDetachedFromWindow()中置为null。因为我们传入的etchat所在窗口已经关闭,所以获取的 windowToken为null。

再来看 mServedView不为null的值,发现是我 DialogFragment 依附的 activity的布局控件,可以理解为当前获取焦点的控件,因此可以传入activity中当前焦点所在的view试试,代码改为:

    override fun onDismiss(dialog: DialogInterface) {val view = activity?.window?.currentFocusview?.let { imm?.hideSoftInputFromWindow(it.windowToken, 0) }super.onDismiss(dialog)}

运行后软键盘正常关闭,OK,问题解决。

本以为问题已解决,但是在操作的时候发现会有偶发的关闭失效,发现又是 mServedView == null,原因未知,没办法,这种方式不够保险。

自定义Dialog在dismiss之前通知 DialogFragment 关闭软键盘

转变思路,既然在 DialogFragment 中无法提前监听dialog关闭,那就自定义Dialog重写dismiss方法,在Dialog关闭之前告知 DialogFragment 关闭软键盘

    class EditDialog(context: Context?, theme: Int) : Dialog(context, theme) {override fun dismiss() {onDismissListener?.invoke()super.dismiss()}var onDismissListener: (() -> Unit)? = null}override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {val dialog = EditDialog(context, R.style.live_editTextDialogStyle)dialog.onDismissListener = { hideSoftInput() }return dialog}

在DialogFragment的onCreateDialog中创建自定义的Dialog,设置关闭回调。

最后,还有一种方式就是使用全屏dialog,在原先空白区域加一个透明的View,设置view的点击事件去关闭软键盘和弹窗,这样就避免了点击空白处关闭的问题。

DialogFragment自动弹出软键盘,消失时关闭软键盘相关推荐

  1. u盘自动打开html,如何快速禁用U盘自动弹出(播放)功能无需手动关闭弹出窗口

    如何快速禁用U盘自动弹出(播放)功能无需手动关闭弹出窗口 发布时间:2013-08-26 17:04:27   作者:佚名   我要评论 移动硬盘分了N个区的时候需要手动一个一个的关掉自动播放窗口,真 ...

  2. Android中DialogFragment自动弹出输入法

    记录一下刚刚解决的问题,DialogFragment中的EditText获得焦点后自动弹出输入法的办法. 网上找到好多资料,但是很多已经过时或者不是针对dialog的设置. 现在将我测试成功的方法记录 ...

  3. 从页面底部向上弹出dialog,消失时逐渐向下(转)

    我想实现一个效果,从底部向上逐渐弹出.如下图所示: 1.点击 显示 按钮时,一个dialog对话框从底部慢慢向上弹出. 2.关闭dialog时, dialog缓慢的移动向底部消失.很平滑的效果.   ...

  4. Android 软键盘自动弹出和关闭

    在我们写修改信息或者搜索,修改密码等界面的时候,用户进入这个界面的主要目的就是输入修改/查找 某些信息,为了用户体验应该自动弹出软键盘而不是让用户主动点击输入框才弹出. 1.软键盘的自动弹出 priv ...

  5. xp系统一直跳出宽带连接服务器,电脑开机后会自动弹出自动宽带连接提示窗口 怎么关闭?...

    自从电脑接宽带后,我们经常会用到宽带连接,甚至为了方便操作,我们直接让电脑开机就自动宽带连接了,而当我们接上路由后,我们会发现电脑再也不用宽带连接了,而这时电脑由于之前被我们设置为开机自动宽带连接,而 ...

  6. android 表情键盘切换,Android仿微信键盘切换效果

    Android 仿微信的键盘切换(录音,表情,文字,其他),IM通讯,类似朋友圈只要涉及到文字等相关的app都会要涉及到键盘的处理,今天就给大家分享一下Android 仿微信的键盘切换. 效果图如下: ...

  7. WIN7/WIN10/WIN11系统下触屏软键盘无法跟随跳出,桌面模式无法自动弹出(随动键盘)

    1.开启自动弹出软键盘的功能. 按组合键 "Win+I" 进入Windows设置,选择设备 > 输入,勾上 "不处于平板电脑模式且未连接键盘时显示触摸键盘" ...

  8. android 页面默认不弹软键盘_Android避免进入页面自动弹出软键盘(真正好用)

    有的时候当我们进入一个有 EditText控件的界面时,会自动弹出软键盘,有的时候会给我们带来不便,有人说可以让EditText不获得焦点,虽然同样可以实现,但是我们有以下两个个更好的方式去实现这个效 ...

  9. Android 仿今日头条评论时键盘自动弹出的效果

    Android 仿今日头条评论时键盘自动弹出的效果:当点击评论时,弹出对话框,同时弹出软键盘,当点击返回键时,将对话框关闭,不只是关闭软键盘. 效果图: 对这个对话框设置一个style效果: < ...

  10. android自动软键盘,Android屏蔽软键盘自动弹出的解决方案

    问题概述 在编辑框输入内容时会弹出软键盘,而手机屏幕区域有限往往会遮住输入界面,我们先看一下问题效果图: 输入用户名和密码时,系统会弹出键盘,造成系统键盘会挡住文本框的问题,如图所示: 输入密码时输入 ...

最新文章

  1. tomcat 运行php_tomcat可以运行php吗
  2. 浅谈 PHP 与手机 APP 开发(API 接口开发)
  3. halcon算子翻译——dev_set_paint
  4. 【经典C#.NET入门教程】管理软件开发必备知识免费视频教程下载
  5. unity实用技术:色盲玩家也能享受好的游戏体验
  6. Google Pixel 2(XL)录像画质提升背后
  7. Java前端笔记-后端Springboot,前端vue,Nginx使前后端分离
  8. 域控制器的常规卸载,Active Directory系列之十三
  9. 毕设题目:Matlab语音加密
  10. Golang代码测试:一点到面用测试驱动开发
  11. 注册ActiveX控件时DllRegisterServer调用失败的解决方法
  12. 将谷歌浏览器(chrome)设置为全黑色主题背景
  13. php screw 密钥,php-screw php代码加密工具用法(整理)
  14. 基于PaddleX构建专属行车助手,为交通安全保驾护航
  15. ArrayList集合源码浅析
  16. 谷歌浏览器好用的复制粘贴插件_好用到炸的谷歌chrome浏览器必备扩展插件(一)...
  17. 用CSS添加鼠标样式-箭头、小手、十字 CSS实现虚线之dotted边框-点虚线、dashed边框-破折号虚线
  18. idea-代码格式化快捷键设置
  19. 垃圾发电厂过磅系统是怎么运作的
  20. Display tag 使用

热门文章

  1. java字符串hash算法_Java常用HASH算法总结【经典实例】
  2. 看完你就知道交换机端口该搭配什么光模块了
  3. android sd卡如何读取,Android应用中怎么读取 sd卡中的数据
  4. mysql.tar.xz怎么安装_.tar.xz文件的解压
  5. 网站外链如何才能被搜索引擎快速收录呢?
  6. 葡萄柚能放冰箱保存吗 葡萄柚怎么保存时间长
  7. asp.net914-自驾游网站的设计与实现
  8. C# 判断是否是节假日
  9. HCIP/HCIE RoutingSwitching / Datacom备考宝典系列(八)VLAN知识点全面总结
  10. mysql加载audit失败_MySQL5.5 安装mcafee mysql-audit插件 不成功