【问题标题】:How to hide status and navigation bars after first touch event?第一次触摸事件后如何隐藏状态和导航栏?
【发布时间】:2015-08-25 21:17:26
【问题描述】:

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

【问题讨论】:

    标签: android show-hide android-statusbar


    【解决方案1】:

    我通过使用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

    【讨论】:

    • 这种方法可以很好地隐藏条,但是当显示软键盘时,它会突然出现......知道是什么原因造成的吗?
    • 不确定是什么原因导致闪烁,但尝试使用此属性android:windowSoftInputMode
    【解决方案2】:

    -如果你想隐藏导航栏,你会遇到第一次触摸事件的问题,你的应用将无法对它做任何事情。

    -如果你愿意,可以在一定时间后使用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 是一个 Runnable 对象,它隐藏了 systemUI。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-26
      相关资源
      最近更新 更多