Навигация в иммерсивном режиме становится липкой после громкого нажатия или минимизации-восстановления
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;
}
}
После первого запуска
После нажатия кнопок громкости или после недавнего нажатия приложений дважды
Я видел, что приложение QuickPic не имеет этой ошибки. Интересно, как они это пропустили.
3 ответа
У меня работает следующий код:
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);
}
}
});
}
И позвонил слушателю на onCreate
а также onResume
методы:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
updateUI();
}
@Override
public void onResume() {
super.onResume();
updateUI();
}
Мое решение состоит в том, чтобы установить флаги UI-Visibility в трех местах:
- При получении фокуса
- В onResume
- В слушателе OnSystemUiVisibilityChangeListener
Третий решил мою проблему. Другие могут быть не нужны, но я их оставил. Вот как это выглядит:
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 () вызывается в onCreate().
У меня была та же проблема, и я решил ее простым обходным путем. Хотя я не мог найти теоретическую причину этого обходного пути, но он все равно работал для меня.
Кажется, что при нажатии кнопки громкости "флаги", относящиеся к "режиму погружения", сбрасываются. И я думаю, именно поэтому режим погружения отключен, и режим погружения не восстанавливается автоматически.
Поэтому я попытался установить "флаги" после нажатия кнопки громкости с "запущенным" объектом.
Итак, это работает так:
режим погружения -> кнопка громкости нажата (флажки сняты) -> через 500 мс, работающий объект снова устанавливает флажки -> режим погружения восстановлен
1. Сначала определите объект runnable для установки флагов
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. Опубликовать работающий объект с некоторой задержкой в обработчике при нажатии кнопки громкости
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);
}
Я просто отложил это на 500 мс без причины, это не важно.
3. Базовый код для режима погружения с работающим объектом
@Override
public void onWindowFocusChanged(boolean hasFocus)
{
super.onWindowFocusChanged(hasFocus);
if(hasFocus)
{
mHandler.post(decor_view_settings);
}
}
Это отлично сработало на моем приложении.
Таким образом, когда я нажимаю кнопку громкости, режим погружения отключается, и всплывающее меню громкости появляется.
через несколько секунд качелька громкости исчезнет, как и строка состояния и панель навигации.
Надеюсь, эта работа для вас.