2015-08-25 79 views
1

我一直在使用標記SYSTEM_UI_FLAG_FULLSCREENSYSTEM_UI_FLAG_HIDE_NAVIGATION來隱藏和顯示狀態和導航欄。他們工作正常。我在活動開始時隱藏了他們,我想在觸摸事件中再次展示他們。 Android會在第一個觸摸事件中自動顯示它們(這個第一個觸摸事件不會傳遞給我的應用程序)。我打算在一段時間後使用sendMessageDelayed()來隱藏兩個欄。我怎麼能使用這個第一觸摸事件?如何在第一次觸摸事件後隱藏狀態和導航欄?

回答

4

我通過使用View.OnSystemUiVisibilityChangeListener得到了它。當狀態和導航欄都可見時,我在if條件內使用了Handler.sendMessageDelayed。爲了清晰起見,請參見下面的實現。

來源:Responding to UI Visibility Changes

View decorView = getActivity().getWindow().getDecorView(); 
decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {@Override 
    public void onSystemUiVisibilityChange(int visibility) { 
     if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) { 
      // TODO: The system bars are visible. Make any desired 
      Message msg = mHandler.obtainMessage(HIDE_STATUSBAR); //Implement your hide functionality accordingly     
      mHandler.sendMessageDelayed(msg, 3000); 
     } else { 
      // TODO: The system bars are NOT visible. Make any desired 

      } 
     } 
    } 
}); 

這種方法的缺點是不能用你的應用程序中使用的第一觸摸事件。我認爲在這種情況下您必須使用其他方法,如WindowManager.LayoutParamsImmersive Fullscreen Mode

0

- 如果您想隱藏導航欄,您將遇到第一個觸摸事件的問題,您的應用程序將無法對其執行任何操作。

- 如果你願意,你可以使用postDelayed()隱藏一定時間後的酒吧,這裏是我做了什麼:

Runnable navHider = new Runnable() { 
    @Override 
    public void run() { 
     Log.e("HIDING", "hide"); 
     hideSystemUi(); 
    } 

/** Hides StatusBar and NavigationBar */ 
private void hideSystemUi() { 
    if (isLandscape()) { 
     // Set flags for hiding status bar and navigation bar 
     View decorView = ((Activity) context).getWindow().getDecorView(); 
     // Hide the status bar. 
     int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 
     | View.SYSTEM_UI_FLAG_FULLSCREEN 
     | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 
     | View.SYSTEM_UI_FLAG_LAYOUT_STABLE 
     | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; 
     int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE 
       | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; 
     decorView.setSystemUiVisibility(uiOptions); 

    } 
} 

private void setVisibilityChangeListener() { 
    View decorView = ((Activity) context).getWindow().getDecorView(); 
    decorView 
      .setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() { 
       @Override 
       public void onSystemUiVisibilityChange(int visibility) { 
        // Note that system bars will only be "visible" if none 
        // of the 
        // LOW_PROFILE, HIDE_NAVIGATION, or FULLSCREEN flags are 
        // set. 
        if (isLandscape()) { 
         if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) { 
          getHandler().postDelayed(navHider, 
            UI_VISIBILITY_TIME); 
         } 
        } 
       } 
      }); 
} 

我們正在做的事情是:

- 首先,在navHider是隱藏systemUI的Runnable對象。 (請注意,我們也使用LAYOUT_STABLE標誌,因此內容會顯示在狀態欄和導航欄的後面,我們不需要調整其大小內容)。

- 第三,我們使用的是systemUIVisibilityChangeListener,這樣在用戶與屏幕交互並顯示狀態和導航條後,我們使用postDelayed(),其中UIVisibility時間是您要的時間在我們隱藏狀態和導航條之前等待

您還可以在每次觸摸時顯示/隱藏狀態欄事件(或點擊一個按鈕,等等),我們只能在狀態欄而不是導航欄中做到這一點:

/** Hides StatusBar and NavigationBar */ 
private void hideSystemUi() { 
    if (isLandscape()) { 
     // Set flags for hiding status bar and navigation bar 
     View decorView = ((Activity) context).getWindow().getDecorView(); 
     // // Hide the status bar. 
     int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE 
       | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; 
     decorView.setSystemUiVisibility(uiOptions); 

     Window window = ((Activity) context).getWindow(); 
     window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); 
     window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN); 
     ((Activity) context).getActionBar().hide(); 
     isShowing = false; 
    } 
} 

private void showSystemUi() { 
    View decorView = ((Activity) context).getWindow().getDecorView(); 
    Window window = ((Activity) context).getWindow(); 
    decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE 
      | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); 
    window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); 
    window.clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN); 
    ((Activity) context).getActionBar().show(); 
    isShowing = true; 
} 

@Override 
public boolean onInterceptTouchEvent(MotionEvent event) { 
    if (event.getAction() == MotionEvent.ACTION_UP) { 
     if (isShowing) { 
      Log.e("onInterceptTouchEvent", "Hiding System UI"); 
      hideSystemUi(); 
     } else { 
      Log.e("onInterceptTouchEvent", "Showing System UI"); 
      showSystemUi(); 
     } 
    } 
    return super.onInterceptTouchEvent(event); 

} 

注意,在這些2種方法:hideSystemUI()showSystemUI(),避免了惱人的「第一次接觸事件「,我們使用舊的4.0標誌,用於隱藏狀態欄。

我在我的ViewPager(我用來顯示圖像)中使用此代碼,所以我可以覆蓋onInterceptTouchEvent()方法。在這裏我用一個簡單的布爾值檢查系統是否顯示。您還需要使用MotionEvent.ACTION_UP,這將允許您滾動ViewPager,而不會意外地顯示/隱藏狀態欄,因此您可以以全屏模式滾動。

你可以做的是做一個自定義佈局(比如說RelativeLayout),它擴展了ViewGroup,你可以覆蓋onInterceptTouchEvent並進行這個實現。觸摸事件僅適用於CustomRelativeLayout,所以如果您希望它在整個活動中都能正常工作,請使用match_parent屬性爲height/width製作CustomRelativeLayout您的基本佈局。

以下是顯示和隱藏狀態和導航欄的信息。 https://developer.android.com/training/system-ui/status.html https://developer.android.com/training/system-ui/navigation.html

這是一個鏈接,用於管理觸摸事件。 https://developer.android.com/training/gestures/viewgroup.html

0

謝謝@prudhvi! 我解決了我的問題。 我猜

Runnable navHider = new Runnable() { 
    @Override 
    public void run() { 
     if (isLandscape()) { 
      Log.e("HIDING", "hide"); 
      hideSystemUi(); 
     } 
    } 
} 

是更好,如果你想隱藏UI僅景觀配置。因爲您可以在隱藏系統UI之前將配置更改爲肖像,因此可以使用