问题
I use immersive-sticky mode to hide the navigation bar and action bar:
@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();
}
}
}
When a Spinner
is touched, the navigationBar
is shown and immersive mode is disabled.
This solution works for Dialogs:
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);
But Spinner
doesn't have show()
method that I could overwrite.
How can I prevent System UI from showing when a Spinner is touched?
Edit: this question is about keeping the Navigation Bar hidden (BackButton, HomeButton and RecentTasksButton). I'm already using FLAG_FULLSCREEN
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
回答1:
I know this is super late, but I finally found a solution to this here:
Just call this on your spinner before using it:
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:
For everyone who, like me, will start rewriting solution pasted by @Quinn from Kotlin to Java and later they will find out that on the linked git repo is the solution in Java also, I am pasting it here:
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();
}
}
来源:https://stackoverflow.com/questions/49534072/how-do-i-maintain-the-immersive-mode-in-spinner