【问题标题】:How do I maintain the Immersive Mode in Spinner?如何在 Spinner 中保持沉浸式模式?
【发布时间】:2018-09-07 02:42:55
【问题描述】:

我使用沉浸式粘性模式隐藏导航栏和操作栏:

@TargetApi(19)
private void setImmersiveMode() {
    if (Build.VERSION.SDK_INT >= 19) {
        View decorView = getWindow().getDecorView();
        int uiOptions = getImmersiveUiOptions(decorView);
        decorView.setSystemUiVisibility(uiOptions);
        ActionBar actionBar = getActionBar();
        if (null!=actionBar) {
            actionBar.hide();
        }
    }
}

触摸Spinner 时,会显示navigationBar 并禁用沉浸式模式。

This solution 适用于对话框:

dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
dialog.show();
dialog.getWindow().getDecorView().setSystemUiVisibility(
context.getWindow().getDecorView().getSystemUiVisibility());
dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);

但是Spinner 没有我可以覆盖的show() 方法。

如何防止在触摸 Spinner 时显示系统 UI?

编辑:这个问题是关于隐藏导航栏(BackButton、HomeButton 和RecentTasksButton)。我已经在使用FLAG_FULLSCREEN

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);   

【问题讨论】:

标签: android android-spinner android-immersive


【解决方案1】:

我知道这已经很晚了,但我终于找到了解决这个here的方法:

在使用前在你的微调器上调用它:

import android.widget.PopupWindow
import android.widget.Spinner

fun Spinner.avoidDropdownFocus() {
    try {
        val isAppCompat = this is androidx.appcompat.widget.AppCompatSpinner
        val spinnerClass = if (isAppCompat) androidx.appcompat.widget.AppCompatSpinner::class.java else Spinner::class.java
        val popupWindowClass = if (isAppCompat) androidx.appcompat.widget.ListPopupWindow::class.java else android.widget.ListPopupWindow::class.java

        val listPopup = spinnerClass
                .getDeclaredField("mPopup")
                .apply { isAccessible = true }
                .get(this)
        if (popupWindowClass.isInstance(listPopup)) {
            val popup = popupWindowClass
                    .getDeclaredField("mPopup")
                    .apply { isAccessible = true }
                    .get(listPopup)
            if (popup is PopupWindow) {
                popup.isFocusable = false
            }
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

【讨论】:

    【解决方案2】:

    对于像我一样将开始将@Quinn 粘贴的解决方案从 Kotlin 重写到 Java 的每个人,后来他们会发现 the linked git repo 也是 Java 中的解决方案,我将其粘贴在这里:

    import android.widget.ListPopupWindow;
    import android.widget.PopupWindow;
    import android.widget.Spinner;
    
    public static void avoidSpinnerDropdownFocus(Spinner spinner) {
        try {
            Field listPopupField = Spinner.class.getDeclaredField("mPopup");
            listPopupField.setAccessible(true);
            Object listPopup = listPopupField.get(spinner);
            if (listPopup instanceof ListPopupWindow) {
                Field popupField = ListPopupWindow.class.getDeclaredField("mPopup");
                popupField.setAccessible(true);
                Object popup = popupField.get((ListPopupWindow) listPopup);
                if (popup instanceof PopupWindow) {
                    ((PopupWindow) popup).setFocusable(false);
                }
            }
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    

    【讨论】:

    • 哈哈,对不起!
    • 没问题 :) 谢谢你的回答。
    • 我在 Android 9 上遇到了这个问题,这与使用 androidx.appcompat:appcompat 版本 1.0.2 有关。升级到 1.2.0 避免了该问题并使此解决方法再次起作用。
    猜你喜欢
    • 2016-04-26
    • 2021-05-31
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2016-08-25
    • 2020-02-04
    • 2019-10-22
    • 1970-01-01
    相关资源
    最近更新 更多