我一直在使用標記SYSTEM_UI_FLAG_FULLSCREEN
和SYSTEM_UI_FLAG_HIDE_NAVIGATION
來隱藏和顯示狀態和導航欄。他們工作正常。我在活動開始時隱藏了他們,我想在觸摸事件中再次展示他們。 Android會在第一個觸摸事件中自動顯示它們(這個第一個觸摸事件不會傳遞給我的應用程序)。我打算在一段時間後使用sendMessageDelayed()
來隱藏兩個欄。我怎麼能使用這個第一觸摸事件?如何在第一次觸摸事件後隱藏狀態和導航欄?
回答
我通過使用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.LayoutParams或Immersive Fullscreen Mode。
- 如果您想隱藏導航欄,您將遇到第一個觸摸事件的問題,您的應用程序將無法對其執行任何操作。
- 如果你願意,你可以使用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
謝謝@prudhvi! 我解決了我的問題。 我猜
Runnable navHider = new Runnable() {
@Override
public void run() {
if (isLandscape()) {
Log.e("HIDING", "hide");
hideSystemUi();
}
}
}
是更好,如果你想隱藏UI僅景觀配置。因爲您可以在隱藏系統UI之前將配置更改爲肖像,因此可以使用
- 1. 觸摸導航欄時隱藏鍵盤
- 2. 導航欄狀態,顯示和隱藏底部導航欄
- 3. 在Android 4.0中導航欄劫持第一觸摸事件
- 4. 隱藏導航欄和觸摸工具欄
- 5. 顯示和隱藏Sencha觸摸導航視圖的事件
- 6. 同時隱藏狀態欄和導航欄,如圖片應用
- 7. 同時隱藏/顯示導航欄,工具欄和狀態欄
- 8. 如何隱藏可可觸摸中的狀態欄?
- 9. Android的隱藏操作欄,狀態欄和導航控制
- 10. 如何在視頻播放器中隱藏狀態欄和觸摸顯示?
- 11. 如何隱藏導航欄?
- 12. 如何隱藏導航欄?
- 13. 隱藏狀態欄,但在封面上仍攔截iPhone觸摸
- 14. 在隱藏狀態欄及其背景時滾動時隱藏導航欄
- 15. 如何隱藏狀態欄?
- 16. 如何隱藏狀態欄?
- 17. 在故事板中隱藏導航欄
- 18. 如何在第一頁顯示之前隱藏導航欄?
- 19. 如何在第一個視圖上隱藏導航欄
- 20. 當單擊觸摸視圖時隱藏標籤欄和導航欄
- 21. 如何隱藏和顯示狀態欄
- 22. 隱藏導航欄
- 23. 隱藏導航欄?
- 24. 隱藏導航欄
- 25. 隱藏導航欄
- 26. 隱藏狀態欄攔截iPad上的觸摸
- 27. 導航欄位於來自TableView的隱藏狀態欄
- 28. 導航欄隱藏在iOS 7中時,如何更改狀態欄的顏色?
- 29. UIRefreshControl隱藏在導航欄後面。
- 30. Xcode tableview隱藏在導航欄後面