2013-11-03 2 views
15

я в настоящее время с помощью погружения в режим 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, но он не запускается для этого конкретного события.

Любые идеи?

ответ

7

Из видео разработчика Android Developers, когда вы находитесь в режиме погружения в липкость, приложение не уведомляется.

Иммерсивный липкий режим начинается в 6:56 и около 7:25 Роман Нурик сообщает, что слушатель не будет запущен.

Это видео: http://youtu.be/cBi8fjv90E4?t=6m56s

+0

Хм, это раздражает. Интересно, есть ли неофициальный способ его обнаружить. – Glitch

+1

Я думаю, что это ошибка дизайна, когда SYSTEM_UI_FLAG_HIDE_NAVIGATION не очищается в липком режиме, когда система ui становится видимой.Если у вас есть ui с сложным обнаружением жестов, на самом деле нет способа отличить салфетки вниз (которые следует игнорировать) от других жестов (которые должны быть обработаны). –

+0

Я полностью согласен с этим, потому что это имеет значение, если ваш контент наложен на полупрозрачный вид. Я понимаю, почему они не хотели, чтобы существующие триггеры срабатывали, но они могли по крайней мере добавить новое событие или новый флаг. –

1

В 4.4, приложение не получит каких-либо указаний, когда переходные системы бары открываются или автоматически скрыты (под IMMERSIVE_STICKY), либо с помощью OnSystemUiVisibilityChangeListener или других средств.

Вы можете прислушиваться к ошибкам, подобным system gesture listener, но это не является частью публичного api, оно может меняться в будущих выпусках и различаться по всем устройствам.

Мне любопытно, что вы хотите сделать, когда кратковременные системные бары отображаются/скрыты.

+0

Спасибо, я дам это. На данный момент я просто играю с визуальными эффектами, на данный момент нет точной цели. – Glitch

4

ОБНОВЛЕНО ОТВЕТ:

установить 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 ОТВЕТ:

это противно, но это решение 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); 
       } 

      } 
     }); 
    } 
+0

Работает ли он, когда пользователь меняет громкость устройства с помощью аппаратных кнопок, и диалоговое окно появляется над приложением? В моих тестах, если первое, что пользователь делает после открытия приложения immersive, это изменение громкости с помощью аппаратных кнопок, видимость приложения не изменяется. – mmathieum

4

Я нашел решение, которое мне подходит, даже если она не совершенна. Я устанавливаю видимость пользовательского интерфейса в View.SYSTEM_UI_FLAG_IMMERSIVE вместо View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY, и когда я получаю обратный вызов onSystemUiVisibilityChange, я задерживаю сообщение обработчику, чтобы сбросить видимость пользовательского интерфейса. Вот код:

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); 
    } 
} 
+0

Почему вы задерживаетесь перед вызовом setFullScreen? –

+1

Потому что, если я этого не сделаю, он будет скрывать строку состояния напрямую, и я хотел бы подражать способу работы View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY. –

+0

ОК, спасибо. Иногда я получаю смешное условие, когда onSystemUiVisibilityChange, похоже, вызывается несколько раз. Мне было интересно, была ли ваша задержка, чтобы исправить это. –

Смежные вопросы