Android иммерсивный режим: работает только один раз, панель инструментов не скрывается или не закрывается - PullRequest
0 голосов
/ 28 мая 2020

Скопировал это из https://developer.android.com/training/system-ui/immersive.html, и он работает: приложение переходит в полноэкранный режим, а пользовательский интерфейс системы возвращается при нажатии в любом месте.

    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) нажатие Anywhere возвращает системный интерфейс, который затем скрывает <androidx.appcompat.widget.Toolbar>, делая невозможным нажатие кнопки Settings ; и

(3) после того, как системный пользовательский интерфейс был возвращен, он больше никогда не исчезает ( см. приложение YouTube, где оно снова исчезает через короткое время).

Что я не так понял?

1 Ответ

0 голосов
/ 06 июня 2020

Итак, это заняло у меня 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();
                }
            }
        }

т.е. всякий раз, когда отображается пользовательский интерфейс, скрыть его снова с опозданием.

...