Android 按下音量或最小化恢复后,沉浸式模式导航变得粘滞
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21164836/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Immersive mode navigation becomes sticky after volume press or minimise-restore
提问by Yaroslav Mytkalyk
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
this.getWindow().getDecorView().setSystemUiVisibility(getSystemUiFlags());
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
private static int getSystemUiFlags() {
return View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
}
}
After first start
第一次启动后
After volume buttons pressed or after recent apps pressed twice
按下音量按钮后或按下最近的应用程序两次后
I saw QuickPic app doesn't have this bug. I wonder how they omitted it.
我看到 QuickPic 应用程序没有这个错误。我想知道他们是如何省略它的。
回答by emjee
The following code works for me:
以下代码对我有用:
public void updateUI() {
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(
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);
}
}
});
}
And called the listener on onCreate
and onResume
methods:
并调用侦听器onCreate
和onResume
方法:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
updateUI();
}
@Override
public void onResume() {
super.onResume();
updateUI();
}
回答by Chris
My solution is to set the UI-Visibility flags in three places:
我的解决方案是在三个地方设置 UI-Visibility 标志:
- When getting the focus
- In onResume
- In the OnSystemUiVisibilityChangeListener listener
- 获得焦点时
- 在简历中
- 在 OnSystemUiVisibilityChangeListener 监听器中
The third solved my problem. The others might not be needed, but I left them. This is what is looks like:
第三个解决了我的问题。其他人可能不需要,但我离开了他们。这是看起来像:
private void setupMainWindowDisplayMode() {
View decorView = setSystemUiVisilityMode();
decorView.setOnSystemUiVisibilityChangeListener(new OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
setSystemUiVisilityMode(); // Needed to avoid exiting immersive_sticky when keyboard is displayed
}
});
}
private View setSystemUiVisilityMode() {
View decorView = getWindow().getDecorView();
int options;
options =
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_STICKY;
decorView.setSystemUiVisibility(options);
return decorView;
}
setupMainWindowDisplayMode() gets called in onCreate().
setupMainWindowDisplayMode() 在 onCreate() 中被调用。
回答by Sangseok
I had the same problem, and I solved it with a simple workaround. Even though I couldn't find the theoretical reason of this workaround, but it worked for me anyway.
我遇到了同样的问题,我用一个简单的解决方法解决了它。尽管我找不到这种解决方法的理论原因,但无论如何它对我有用。
It seems like when a volume button is pressed, the 'flags' related to the 'immersive mode' are cleared. And I think that's why the immersive mode is disabled and the immersive mode is not restored automatically.
似乎当按下音量按钮时,与“沉浸式模式”相关的“标志”会被清除。我认为这就是沉浸模式被禁用并且沉浸模式不会自动恢复的原因。
Therefore, I tried to set the 'flags' after pressing the volume button with 'runnable' object.
因此,我尝试在按下带有“可运行”对象的音量按钮后设置“标志”。
So, it works like this:
所以,它是这样工作的:
immersive mode -> volume button pressed(flags cleared) -> 500ms later, the runnable object sets the flags again -> immersive mode restored
沉浸式模式 -> 按下音量按钮(清除标志)-> 500 毫秒后,可运行对象再次设置标志 -> 沉浸式模式恢复
1. First, define the runnable object to set the flags
1.首先定义runnable对象来设置flags
private Runnable decor_view_settings = new Runnable()
{
public void run()
{
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);
}
};
2. Post the runnable object with some delay to a handler when a volume button is pressed
2.当按下音量按钮时,将可运行对象延迟一段时间发布到处理程序
private Handler mHandler = new Handler();
...
...
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if(keyCode == KeyEvent.KEYCODE_BACK)
{
finish();
}
else if(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP)
{
mHandler.postDelayed(decor_view_settings, 500);
}
return super.onKeyDown(keyCode, event);
}
I just delayed it for 500ms with no reason, it's not important.
我只是无缘无故地延迟了 500 毫秒,这并不重要。
3. The basic code for immersive mode with runnable object
3.具有可运行对象的沉浸模式的基本代码
@Override
public void onWindowFocusChanged(boolean hasFocus)
{
super.onWindowFocusChanged(hasFocus);
if(hasFocus)
{
mHandler.post(decor_view_settings);
}
}
It worked perfectly on my app.
它在我的应用程序上完美运行。
So, when I press a volume button, the immersive mode is disabled and the volume rocker pops up.
因此,当我按下音量按钮时,沉浸模式被禁用,音量摇杆会弹出。
after a few seconds, the volume rocker disappears and so does the status bar and the navigation bar.
几秒钟后,音量摇杆消失,状态栏和导航栏也消失。
Hope this work for you.
希望这对你有用。