我一直在使用标志来隐藏和显示状态栏和导航栏SYSTEM_UI_FLAG_FULLSCREEN
。SYSTEM_UI_FLAG_HIDE_NAVIGATION
他们工作正常。我在活动开始时将它们隐藏起来,我想在触摸事件中再次显示它们。Android 会在第一次触摸事件时自动显示它们(第一次触摸事件不会传递给我的应用程序)。我正在考虑sendMessageDelayed()
在一段时间后用来隐藏两个栏。我怎么能使用这个第一次触摸事件?
2 回答
我通过使用得到它View.OnSystemUiVisibilityChangeListener
。当状态栏和导航栏都可见时,我刚刚使用了Handler.sendMessageDelayed
if 条件。为了清楚起见,请参阅下面的实现。
来源:响应 UI 可见性更改
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或沉浸式全屏模式。
-如果你想隐藏导航栏,你会遇到第一次触摸事件的问题,你的应用程序将无法对它做任何事情。
-如果你想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
是一个可运行的对象,它隐藏了系统用户界面。
-其次,hideSystemUi
方法是设置隐藏状态和导航栏的UI选项标志(注意我们也使用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);
}
请注意,在这两种方法中:hideSystemUI()
和showSystemUI()
,为了避免烦人的“第一次触摸事件”,我们使用旧的 4.0 之前的标志来隐藏状态栏。
我在我的ViewPager
(我用它来显示图像)中使用这个代码,所以我可以覆盖这个onInterceptTouchEvent()
方法。在这里,我用一个简单的布尔值检查系统是否显示。您还需要使用MotionEvent.ACTION_UP
,这将允许您滚动ViewPager
,而不会意外显示/隐藏状态栏,因此您可以在全屏模式下滚动。
您可以做的是制作一个自定义布局(让我们说RelativeLayout
),它可以扩展ViewGroup
并且您可以覆盖onInterceptTouchEvent
并进行此实现。触摸事件仅适用于此CustomRelativeLayout
,因此如果您希望它适用于整个活动,只需使用高度/宽度属性制作CustomRelativeLayout
基本布局。match_parent
这是显示和隐藏状态和导航栏的信息。 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