首页 > 解决方案 > Android 沉浸式模式:仅工作一次,工具栏既不隐藏也不遮挡

问题描述

https://developer.android.com/training/system-ui/immersive.html复制它,它可以工作:应用程序进入全屏状态,当您点击任意位置时系统 UI 会返回。

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

    private fun hideSystemUI() {
        // Enables regular immersive mode.
        // For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE.
        // Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY
        window.decorView.systemUiVisibility = (
                //View.SYSTEM_UI_FLAG_IMMERSIVE
                // Set the content to appear under the system bars so that the
                // content doesn't resize when the system bars hide and show.
                /*or*/ View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                // Hide the nav bar and status bar
                or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                or View.SYSTEM_UI_FLAG_FULLSCREEN)
    }

然而,

(1)我的应用程序<androidx.appcompat.widget.Toolbar>没有隐藏,但它应该被隐藏;

(2)点击任意位置会返回系统UI,然后隐藏,<androidx.appcompat.widget.Toolbar>从而无法单击“设置”按钮;和

(3)恢复系统 UI 后,它再也不会消失(参见YouTube 应用程序,它会在短时间内再次消失)。

我做错了什么?

标签: android-studioandroid-layoutkotlin

解决方案


所以这花了我8天!

这一切都在MainActivity.kt

这是进行隐藏的机器

    private val hideHandler = Handler()
    private val hideRunnable = Runnable {
        // Enables regular immersive mode.
        // For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE.
        // Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY
        Log.i("PSAMFD", "*************** hideRunnable")

        window.decorView.systemUiVisibility = (
                View.SYSTEM_UI_FLAG_IMMERSIVE
                // Set the content to appear under the system bars so that the
                // content doesn't resize when the system bars hide and show.
                or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                // Hide the nav bar and status bar
                or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                or View.SYSTEM_UI_FLAG_FULLSCREEN
                )

        getSupportActionBar()?.hide()
    }

我们需要在启动时运行它

    override fun onPostCreate(savedInstanceState: Bundle?) {
        super.onPostCreate(savedInstanceState)

        // Trigger the initial hide() shortly after the activity has been
        // created, to briefly hint to the user that UI controls
        // are available.
        hideRunnable.run()
    }

SYSTEM_UI_FLAG_IMMERSIVE意味着用户必须从边缘滑动而不仅仅是触摸。这意味着他们的触摸不会与应用程序的触摸(例如按钮按下和滚动)混淆。

最后,我们必须在用户从边缘滑动后重新隐藏。臭虫对 API 的混乱意味着根据 Android 版本有两种方法可以做到这一点(这在onCreate

        if(Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
            window.decorView.setOnApplyWindowInsetsListener { view, insets ->
                Log.i("PsaMfd", "onApplyWindowInsets.insets = " + insets.toString())
                if (insets.hasInsets()) {
                    getSupportActionBar()?.show();

                    // Schedule a runnable to hide again
                    hideHandler.removeCallbacks(null)
                    hideHandler.postDelayed(hideRunnable, 3000.toLong())
                } else {
                    getSupportActionBar()?.hide();
                }
                insets
            }
        }
        else {
            window.decorView.setOnSystemUiVisibilityChangeListener { visibility ->
                Log.i(
                    "PsaMfd",
                    "setOnSystemUiVisibilityChangeListener.visibility = " + visibility.toString()
                )
                if (visibility and View.SYSTEM_UI_FLAG_FULLSCREEN == 0) {
                    getSupportActionBar()?.show();

                    // Schedule a runnable to hide again
                    hideHandler.removeCallbacks(null)
                    hideHandler.postDelayed(hideRunnable, 3000.toLong())
                } else {
                    getSupportActionBar()?.hide();
                }
            }
        }

即,每当显示 UI 时,延迟后再次隐藏它。


推荐阅读