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

2018-07-17  本文已影响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
        }
    }

最终效果

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

猜你喜欢

热点阅读