美文网首页
EditText & 巧妙解决软件盘与沉浸式冲突

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

作者: 南窗云 | 来源:发表于2018-07-17 10:26 被阅读0次

    实现沉浸式

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

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

    最终效果

    你会看到透明的导航栏,但是这是系统调用键盘时带出的,右下角的按钮还可以切换键盘
    不过上述情况不影响使用,因为键盘隐藏的时候,又回到了沉浸式!

    相关文章

      网友评论

          本文标题:EditText & 巧妙解决软件盘与沉浸式冲突

          本文链接:https://www.haomeiwen.com/subject/rkkwpftx.html