如何在Spinner中保持沉浸模式?

6
我使用沉浸式粘性模式隐藏导航栏和操作栏:
@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”,并禁用沉浸模式。
解决方案适用于对话框:
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);   

1
可能是setSystemUIVsibility full screen disables when using Spinner的重复问题。 - Vidhi Dave
2个回答

7

我知道可能已经晚了,但我终于在这里找到了解决方法:

在使用下拉列表之前,先调用以下代码:

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()
    }
}

1

对于所有像我一样打算将@Quinn粘贴的Kotlin解决方案改写为Java的人,后来他们会发现在链接的git仓库中也有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();
    }
}

哈哈,对不起! - Quinn
没问题 :) 谢谢你的回答。 - Panicum
我在Android 9上遇到了一个问题,与使用androidx.appcompat:appcompat版本1.0.2有关。升级到1.2.0可以避免这个问题,并使这个解决方法再次起作用。 - Wim Deblauwe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接