EditText & 巧妙解决软件盘与沉浸式冲突

实现沉浸式

一般沉浸式用于横屏展示,尤其是华为等有导航栏的

    override fun onWindowFocusChanged(hasFocus: Boolean) {
        super.onWindowFocusChanged(hasFocus)
        if (hasFocus) setNavigationBarStatusBarTranslucent(this)
    }


    //  沉浸式
    private fun setNavigationBarStatusBarTranslucent(activity: Activity) {
        if (Build.VERSION.SDK_INT >= 21) {
            val decorView = activity.window.decorView
            val option = (View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    or View.SYSTEM_UI_FLAG_FULLSCREEN
                    or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
            decorView.systemUiVisibility = option
        }
    }

效果

沉浸式

冲突

键盘弹出,导航栏和状态栏会出现;隐藏键盘仍不消失

而且遮盖了内容展示区,特别丑

隐藏键盘仍不消失

只有下拉然后再次回到界面才会消失

原因是 onWindowFocusChanged(hasFocus: Boolean) 方法,只有在当前window 失去或得到焦点时,才会被调用。
hasFocus 为 true 表示得到焦点。而我们正是在得到焦点时进行了沉浸式处理!

   override fun onWindowFocusChanged(hasFocus: Boolean) {
        super.onWindowFocusChanged(hasFocus)
        if (hasFocus) setNavigationBarStatusBarTranslucent(this)
    }

需要注意的是,键盘的隐藏和显示并不触发 onWindowFocusChanged 方法
(已打 log 测试过,感兴趣的童鞋可以试试)
这让我放弃了在 onWindowFocusChanged 添加判段处理的决定。

解决方案

灵感突然出现,既然我们 在得到焦点时进行了沉浸式处理,说明我们可以控制在什么时候使其沉浸式!(虽然像是废话,但是这使我灵机一动)。
为什么我们不监听键盘的显示和隐藏?然后无论显示还是隐藏都使其沉浸式!
这就是解决方案!!!

  //键盘监听,无论是显示还是隐藏,都调用沉浸式方法
        window.findViewById<View>(android.R.id.content).apply {
            var rootViewVisibleHeight = 0
            viewTreeObserver.addOnGlobalLayoutListener {
                val rect = Rect()
                getWindowVisibleDisplayFrame(rect)
                when {
                    rootViewVisibleHeight == 0 -> rootViewVisibleHeight = rect.height()
                    rootViewVisibleHeight - rect.height() > 200 -> {
                        //显示了
                        setNavigationBarStatusBarTranslucent(this@TaskDetailActivity)
                    }
                    rect.height() - rootViewVisibleHeight > 200 -> {
                        //隐藏了
                        setNavigationBarStatusBarTranslucent(this@TaskDetailActivity)
                    }
                }
            }
        }

setNavigationBarStatusBarTranslucent(this@TaskDetailActivity) 方法代码如下:

    //  沉浸式
    private fun setNavigationBarStatusBarTranslucent(activity: Activity) {
        if (Build.VERSION.SDK_INT >= 21) {
            val decorView = activity.window.decorView
            val option = (View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    or View.SYSTEM_UI_FLAG_FULLSCREEN
                    or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
            decorView.systemUiVisibility = option
        }
    }

最终效果

你会看到透明的导航栏,但是这是系统调用键盘时带出的,右下角的按钮还可以切换键盘

不过上述情况不影响使用,因为键盘隐藏的时候,又回到了沉浸式!
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 177,374评论 25 709
  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明AI阅读 16,117评论 3 119
  • 老公跟我分享:他昨天开着车经过斑马线时,看到有行人就停了下来,有个女的经过他的车前时,向他点头致谢,那一瞬,他的心...
    海风拂霞阅读 162评论 0 0
  • 前情提要: 2014年10月27日,锤子科技官方微博发布声明,自2014年10月30日起,Smartisan T1...
    歌路宽阅读 410评论 0 3
  • 清明小长假之初,吾期友人共去熊猫基地,虽路有阻塞,等候三十又分,终前行。 途中意会: 心悦,情挚,景美,物灵。 夜...
    欣star阅读 158评论 0 0

友情链接更多精彩内容