Detecting when system buttons are visible while using 'immersive mode'

浪子不回头ぞ 提交于 2019-11-28 22:54:12

问题


I'm currently using immersive mode (API 19) for one of my Activities as follows:

getWindow().getDecorView()
            .setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                            | View.INVISIBLE);

This hides the system buttons and notification bar until the user swipes for them back. This works fine, however I wish to detect when the user makes the buttons visible again. I've tried a OnSystemUiVisibilityChangeListener but it does not trigger for this particular event.

Any ideas?


回答1:


From Android Developers video, when you're in immersive sticky mode, the app isn't notified.

Immersive sticky mode starts at 6:56 and around 7:25 Roman Nurik tells that the listener won't be triggered.

This is the video: http://youtu.be/cBi8fjv90E4?t=6m56s




回答2:


UPDATED ANSWER:

Set an OnSystemUiVisibilityChangeListener, force immersive mode when visibility is 0 (rather than 6).

if(android.os.Build.VERSION.SDK_INT >= 19) {
        getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(new OnSystemUiVisibilityChangeListener() {
            @Override
            public void onSystemUiVisibilityChange(int visibility) {
                if(visibility == 0) {
                    getWindow().getDecorView().setSystemUiVisibility(
                            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
                }
            }
        });
    }

OLD, NASTY ANSWER:

this is nasty, but it is a solution IFF you were showing an ActionBar:

  • add an OnGlobalLayoutListener to the ViewTreeObserver of 'action_bar_container'.
  • in the OnGlobalLayoutListener implementation, check if 'action_bar_container' visibility if GONE or not.
  • when it moved from GONE to !GONE (and assuming you were in immersive mode) then force immersive mode again via the setSystemUiVisibility method.

if(android.os.Build.VERSION.SDK_INT >= 19) {
        int actionBarContainerId = Resources.getSystem().getIdentifier("action_bar_container", "id", "android");
        ((ViewGroup)findViewById(actionBarContainerId)).getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                int actionBarContainerId = Resources.getSystem().getIdentifier("action_bar_container", "id", "android");
                ViewGroup actionBarContainer = (ViewGroup) findViewById(actionBarContainerId);
                if(actionBarContainer.getVisibility() == View.GONE) {
                    if(DEBUG) Log.d(TAG, "...PROBABLY IN IMMERSIVE MODE AND ALL IS GOOD!..");
                } else {
                    if(DEBUG) Log.d(TAG, "...PROBABLY NO LONGER IN IMMERSIVE MODE, HEY..");
                    getWindow().getDecorView().setSystemUiVisibility(
                            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
                }

            }
        });
    }



回答3:


I have found a solution that suits me even though it's not perfect. I set the UI visiblity to View.SYSTEM_UI_FLAG_IMMERSIVE instead of View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY and when I receive the onSystemUiVisibilityChange callback, I delay a message to an Handler to reset the UI Visibility. Here is the code :

private static final int FULL_SREEN_MSG = 10;
private static final long TIME_BEFORE_HIDE_UI = 2 * DateUtils.SECOND_IN_MILLIS;

private final Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        if (msg.what == FULL_SREEN_MSG) {
            setFullscreen();
        }
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setFullscreen();
    getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(this);
}

private void setFullscreen() {
    getWindow().getDecorView().setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
                    | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
                    | View.SYSTEM_UI_FLAG_IMMERSIVE);
}

@Override
public void onSystemUiVisibilityChange(int visibility) {
    if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
        mHandler.sendEmptyMessageDelayed(FULL_SREEN_MSG, TIME_BEFORE_HIDE_UI);
    }
}



回答4:


In 4.4, the app will not receive any indication when the transient system bars are revealed or auto-hidden (under IMMERSIVE_STICKY), either via the OnSystemUiVisibilityChangeListener or other means.

You can listen for edge swipes similar to the system gesture listener as a guess, but this is not part of the public api, it may change in future releases and differ across devices.

I'm curious what you want to do when the transient system bars are shown/hidden.



来源:https://stackoverflow.com/questions/19750700/detecting-when-system-buttons-are-visible-while-using-immersive-mode

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!