问题
Working on a client's app that is using immersive mode to hide the navigation bar and status bar on every activity using the following code:
int currentApiVersion = android.os.Build.VERSION.SDK_INT;
final int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
// This work only for android 4.4+
if (currentApiVersion >= 19) {
getWindow().getDecorView().setSystemUiVisibility(flags);
// Code below is for case when you press Volume up or Volume down.
// Without this after pressing valume buttons navigation bar will
// show up and don't hide
final View decorView = getWindow().getDecorView();
decorView
.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
decorView.setSystemUiVisibility(flags);
}
}
});
}
The only problem is that they would like the app to stay in immersive mode and not show the navigation bar even when the soft keyboard is showing to type into an EditText. Can anyone think of a way to always have the navigation buttons (back/hide keyboard, home, etc) always be hidden even while using the keyboard?
回答1:
I've come up with a workaround that checks the navigation bar's status for every internal, try to hide it and check it again (and again).
Here's some piece of code, that makes sure the navigation bar is hidden in 2 seconds after the soft keyboard is closed.
private final Runnable checkSystemUiRunnable = new Runnable() {
@Override
public void run() {
checkHideSystemUI();
}
};
private void checkHideSystemUI() {
// Check if system UI is shown and hide it by post a delayed handler
if (isSystemUiShown) {
hideSystemUI();
handler.postDelayed(checkSystemUiRunnable, SYSTEM_UI_HIDE_DELAY);
}
}
private void hideSystemUI() {
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| View.SYSTEM_UI_FLAG_IMMERSIVE);
}
// In onCreate()
decorView.setOnSystemUiVisibilityChangeListener(
new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
handler.postDelayed(checkSystemUiRunnable, SYSTEM_UI_HIDE_DELAY);
isSystemUiShown = true;
} else {
isSystemUiShown = false;
}
}
});
回答2:
See this. I've searched for over 3 hours for this problem and that solution worked well. I hope it'll be helpful.
回答3:
Here is my solution for this ; First I checked if soft keyboard is showed up or not:
getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
int screenHeight = getWindow().getDecorView().getRootView().getHeight();
int keypadHeight = screenHeight - r.bottom;
//Log.d(TAG, "keypadHeight = " + keypadHeight);
if (keypadHeight > screenHeight * 0.15) {
//Keyboard is opened
hideNavBar();
}
else {
// keyboard is closed
}
}
});
And I have a hideNavBar() method to be triggered when soft keyboard is showed up.
private void hideNavBar() {
if (Build.VERSION.SDK_INT >= 19) {
View v = getWindow().getDecorView();
v.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
This solves the problem of getting navigation bar while there is an Edittext to be typed.
回答4:
Updated:
I have a painting app (Paint Shapes) and this is the configuration I used to always be inside the immersive mode. I use the onWindowFocusChanged
method.
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
来源:https://stackoverflow.com/questions/27115600/android-hide-navigation-bar-stay-in-immersive-mode-with-soft-keyboard-appearance