Как исправить: Значки на панели навигации по-прежнему отображаются, когда открывается всплывающее меню - PullRequest
0 голосов
/ 11 января 2019

Я пытаюсь создать полноэкранное приложение, в котором у пользователя нет доступа к строке состояния и навигации .

Предпочтительно, я бы хотел, чтобы они были полностью удалены , но из того, что я прочитал, это невозможно, пока вы не рутируете устройство

Так что мой вопрос в основном таков: Как скрыть значки панели навигации, когда я показываю всплывающее меню ?

до

BEFORE

ПОСЛЕ

AFTER

Пока что я пробовал:

  • Вызов hideNavigation() до и после отображения всплывающего меню
  • Вызов hideNavigation() в onCreate(), onResume() & onWindowFocusChanged()
  • Запрос фокуса на другой вид
  • Попытка очистить фокус от выпадающего меню (Неудачная попытка, действительно не нашел способа сделать это)
  • Изменение цвета значка, «подделка», оно будет скрыто (Неудачная попытка, действительно не нашел способа сделать это)
  • Использование hideNavigation() в сочетании с Handler (неудачная попытка, возможно, я сделал это неправильно)
  • Попытка настроить некоторые параметры режима COSU / KIOSK (возможно, есть какой-то способ полностью отключить всю панель навигации? Я пока не нашел способа скрыть кнопку )

ДЕЯТЕЛЬНОСТЬ


    class PinCodeActivity, HasTitleBar {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_pin_code)
            initTitleBarWith(this)
            hideNavigation()
        }

        override fun onResume() {
            super.onResume()
            hideNavigation()
        }

        fun hideNavigation() {
            window.decorView.apply {
                systemUiVisibility = FLAGS
            }
        }

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

const val FLAGS = (View.SYSTEM_UI_FLAG_LOW_PROFILE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)

ТИТУЛ-BAR


    fun HasTitleBar.initTitleBarWith(activity: Activity, resId: Int = R.id.titleBar) {
        val langButton = activity.findViewById<View>(resId).findViewById<Button>(R.id.tbLanguageChoiceBtn)
        val wrapper = ContextThemeWrapper(activity, R.style.MyPopupMenu)
        val popupMenu = PopUpLanguageMenu(wrapper, langButton)
        langButton.setOnClickListener {
            activity.hideNavigation()
            popupMenu.showMenu()
            activity.hideNavigation()
        }
    }

всплывающее меню


    class PopUpLanguageMenu constructor(context: Context, view: View) : PopupMenu(context, view) {

        private var popupHelper: MenuPopupHelper

        init {
            val popUpMenu = PopupMenu(context, view).apply {
                inflate(R.menu.menu_language_dropdown)
            }

            popupHelper = MenuPopupHelper(context, popUpMenu.menu as MenuBuilder, view)
            popupHelper.run {
                gravity = Gravity.END
                setForceShowIcon(true)
            }
        }

        fun showMenu() {
            popupHelper.show()
        }
    }

ОЖИДАЕМЫЙ РЕЗУЛЬТАТ : панель навигации и ее значки скрыты, после отображения всплывающего меню значки по-прежнему скрыты

АКТУАЛЬНЫЙ РЕЗУЛЬТАТ : панель навигации и ее значки скрыты, после отображения всплывающего меню значки ПОКАЗАНЫ

1 Ответ

0 голосов
/ 11 января 2019

Появляется панель навигации, потому что в верхней части стека видов вновь отображается новый DecorView (PopupDecorView), на который не влияют установленные вами флаги.

Здесь нет серебряной пули, мой подход - покопаться в WindowManagerGlobal по отражению и поймать обзор, посмотреть на него системные флаги, поэтому после появления PopupMenu удается скрыть панель навигации вправо. после этого (однажды все еще показывается с панели навигации).

Вот код:

override fun onWindowFocusChanged(hasFocus: Boolean) {
    super.onWindowFocusChanged(hasFocus)
    if (hasFocus) {
        hideNavigation()
    } else {
        // When PopupMenu appears, the current Activity looses the focus
        setFlagsOnThePeekView() // Hijack to the current peek view, apply the Flags on it
    }
}

@SuppressLint("PrivateApi")
fun setFlagsOnThePeekView() {
    try {
        val wmgClass = Class.forName("android.view.WindowManagerGlobal")
        val wmgInstance = wmgClass.getMethod("getInstance").invoke(null)
        val viewsField = wmgClass.getDeclaredField("mViews")
        viewsField.isAccessible = true

        val views = viewsField.get(wmgInstance) as ArrayList<View>
        // When the popup appears, its decorView is the peek of the stack aka last item
        views.last().apply { 
            systemUiVisibility = FLAGS
            setOnSystemUiVisibilityChangeListener {
                systemUiVisibility = FLAGS
            }
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
}
...