Обнаружение, когда системные кнопки видны при использовании режима "immersive"
В настоящее время я использую режим immersive (API 19) для одной из моих операций следующим образом:
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
| View.INVISIBLE);
Это скрывает системные кнопки и панель уведомлений, пока пользователь не проведет их обратно. Это прекрасно работает, однако я хочу обнаружить, когда пользователь снова отображает кнопки. Я пробовал OnSystemUiVisibilityChangeListener
, но он не запускается для этого конкретного события.
Любые идеи?
Ответы
Ответ 1
Из видео разработчика Android Developers, когда вы находитесь в режиме погружения в липкость, приложение не уведомляется.
Иммерсивный липкий режим начинается с 6:56 и около 7:25 Роман Нурик говорит, что слушатель не будет запущен.
Это видео: http://youtu.be/cBi8fjv90E4?t=6m56s
Ответ 2
ОБНОВЛЕННЫЙ ОТВЕТ:
Установите OnSystemUiVisibilityChangeListener, принудительно импортируйте режим, когда видимость равна 0 (вместо 6).
if(android.os.Build.VERSION.SDK_INT >= 19) {
getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(new OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
if(visibility == 0) {
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);
}
}
});
}
OLD, NASTY ANSWER:
Это неприятно, но это решение IFF, в котором вы показываете ActionBar:
- добавьте OnGlobalLayoutListener в ViewTreeObserver из файла action_bar_container.
- в реализации OnGlobalLayoutListener, проверьте, отображается ли видимость "action_bar_container", если GONE или нет.
- когда он переместился с GONE на! GONE (и предположил, что вы находитесь в режиме погружения), затем снова принудительно импортируйте режим с помощью метода setSystemUiVisibility.
if(android.os.Build.VERSION.SDK_INT >= 19) {
int actionBarContainerId = Resources.getSystem().getIdentifier("action_bar_container", "id", "android");
((ViewGroup)findViewById(actionBarContainerId)).getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int actionBarContainerId = Resources.getSystem().getIdentifier("action_bar_container", "id", "android");
ViewGroup actionBarContainer = (ViewGroup) findViewById(actionBarContainerId);
if(actionBarContainer.getVisibility() == View.GONE) {
if(DEBUG) Log.d(TAG, "...PROBABLY IN IMMERSIVE MODE AND ALL IS GOOD!..");
} else {
if(DEBUG) Log.d(TAG, "...PROBABLY NO LONGER IN IMMERSIVE MODE, HEY..");
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);
}
}
});
}
Ответ 3
Я нашел решение, которое мне подходит, хотя оно и не идеально. Я устанавливаю видимость пользовательского интерфейса View.SYSTEM_UI_FLAG_IMMERSIVE
вместо View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
, и когда я получаю обратный вызов onSystemUiVisibilityChange
, я задерживаю сообщение обработчику с reset видимостью пользовательского интерфейса. Вот код:
private static final int FULL_SREEN_MSG = 10;
private static final long TIME_BEFORE_HIDE_UI = 2 * DateUtils.SECOND_IN_MILLIS;
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == FULL_SREEN_MSG) {
setFullscreen();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setFullscreen();
getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(this);
}
private void setFullscreen() {
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 // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| View.SYSTEM_UI_FLAG_IMMERSIVE);
}
@Override
public void onSystemUiVisibilityChange(int visibility) {
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
mHandler.sendEmptyMessageDelayed(FULL_SREEN_MSG, TIME_BEFORE_HIDE_UI);
}
}
Ответ 4
В 4.4 приложение не получит каких-либо признаков, когда панели временных индикаторов обнаруживаются или автоматически скрыты (под IMMERSIVE_STICKY), либо через OnSystemUiVisibilityChangeListener, либо другими средствами.
Вы можете прислушиваться к ошибкам, похожим на прослушивание жестов системы, но это не является частью публичного api, оно может изменения в будущих выпусках и разные устройства.
Мне любопытно, что вы хотите сделать, когда кратковременные системные бары отображаются/скрыты.