问题
I added the immersive mode into my app. Here is the code :
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus)
{
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);
}
}
But if I type on the keyboard and I close it (with the back button, by clicking on the screen), the navigation bar stays displayed, I need to reduce/reopen the app to get back the immersive mode.
How can I return to immersive mode after closing the keyboard ?
EDIT : It's a Cordova app
回答1:
This theme: Immersive mode navigation becomes sticky after volume press or minimise-restore covers similar question.
The "delayed" solution proposed there should work in your case.
I stumbled on the same problem and also problem that when you switch between apps nav bar also stays not hidden. I wrote some kind of guide how i solved this problem to keep things together: http://vitiy.info/small-guide-how-to-support-immersive-mode-under-android-4-4/
In short: i combined "delayed handlers" with this:
public void restoreTransparentBars()
{
if (isApplicationInImmersiveMode)
try {
Window w = activity.getWindow();
w.getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
);
w.getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
} catch (Exception e) {}
}
回答2:
Not the best solution but defiantly the most simple and worked for me.
Try this :
final Handler forceImmersive = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
// Enables regular immersive mode.
// For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE.
// Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
// Set the content to appear under the system bars so that the
// content doesn't resize when the system bars hide and show.
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
// Hide the nav bar and status bar
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN);
forceImmersive.postDelayed(this, 1000);
}
};
forceImmersive.postDelayed(runnable, 1000);
回答3:
This is your answer https://stackoverflow.com/a/5993196/772428
You need to re-enable immersion mode on the back press. Here's the code code from that post.
public class EditTextBackEvent extends EditText {
private EditTextImeBackListener mOnImeBack;
public EditTextBackEvent(Context context) {
super(context);
}
public EditTextBackEvent(Context context, AttributeSet attrs) {
super(context, attrs);
}
public EditTextBackEvent(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
if (mOnImeBack != null) mOnImeBack.onImeBack(this, this.getText().toString());
}
return super.dispatchKeyEvent(event);
}
public void setOnEditTextImeBackListener(EditTextImeBackListener listener) {
mOnImeBack = listener;
}
public interface EditTextImeBackListener {
public abstract void onImeBack(EditTextBackEvent ctrl, String text);
}
}
回答4:
Try this. I've searched for over 3 hours and this solution worked well. I hope it'll be useful.
回答5:
I used handlers to detect user inactivity and hide system ui thereafter. It automatically detect if user is not interacting on screen then auto hide system UI after 5 seconds
//Declare handler
private var timeoutHandler: Handler? = null
private var interactionTimeoutRunnable: Runnable? = null
In onCreate()
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
. . .
//Initialise handler
timeoutHandler = Handler();
interactionTimeoutRunnable = Runnable {
// Handle Timeout stuffs here
hideSystemUI()
}
//start countdown
startHandler()
. . .
Method to handle focus change
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
if (hasFocus) hideSystemUI()
}
Hide system Ui
private fun hideSystemUI() {
// Enables regular immersive mode.
// For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE.
// Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_IMMERSIVE
// Set the content to appear under the system bars so that the
// content doesn't resize when the system bars hide and show.
or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
// Hide the nav bar and status bar
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_FULLSCREEN)
}
// Shows the system bars by removing all the flags
// except for the ones that make the content appear under the system bars.
private fun showSystemUI() {
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
}
// reset handler on user interaction
override fun onUserInteraction() {
super.onUserInteraction()
resetHandler()
}
//restart countdown
fun resetHandler() {
timeoutHandler!!.removeCallbacks(interactionTimeoutRunnable);
timeoutHandler!!.postDelayed(interactionTimeoutRunnable, 5*1000); //for 10 second
}
// start countdown
fun startHandler() {
timeoutHandler!!.postDelayed(interactionTimeoutRunnable, 5*1000); //for 10 second
}
来源:https://stackoverflow.com/questions/23456144/return-to-immersive-mode-after-closing-the-keyboard-on-android