2

我一直在使用标志来隐藏和显示状态栏和导航栏SYSTEM_UI_FLAG_FULLSCREENSYSTEM_UI_FLAG_HIDE_NAVIGATION他们工作正常。我在活动开始时将它们隐藏起来,我想在触摸事件中再次显示它们。Android 会在第一次触摸事件时自动显示它们(第一次触摸事件不会传递给我的应用程序)。我正在考虑sendMessageDelayed()在一段时间后用来隐藏两个栏。我怎么能使用这个第一次触摸事件?

4

2 回答 2

7

我通过使用得到它View.OnSystemUiVisibilityChangeListener。当状态栏和导航栏都可见时,我刚刚使用了Handler.sendMessageDelayedif 条件。为了清楚起见,请参阅下面的实现。

来源:响应 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沉浸式全屏模式

于 2015-08-26T20:39:15.617 回答
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是一个可运行的对象,它隐藏了系统用户界面。

-其次,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

于 2015-08-25T22:10:29.640 回答