سؤال

What I want to achieve is a gallery using a full screen mode: when the screen is clicked the controls are shown, and when it's clicked again they are hidden. I have tried setting up an OnClickListener this way to manage the system UI

public void onClick(View v) {
    //toggle state
    systemUIVisible = !systemUIVisible;

    //show controls
    if(systemUIVisible) {
        controlsView.setSystemUiVisibility(
                   View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                           | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                           | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
    }
    //hide controls
    else {
        controlsView.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);
    }
}

And I have set

controlsView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {... }

to manage the visibility of the controls.

The problem is that the system UI visibility is toggled whenever the controlsView is TOUCHED, and not when it's CLICKED.

This leads to the unwanted behaviour of showing the controls when the user is trying to swipe the gallery in fullscreen mode.

Any help is appreciated.

هل كانت مفيدة؟

المحلول

The problem was with the View.SYSTEM_UI_FLAG_HIDE_NAVIGATION flag. From the doc:

There is a limitation: because navigation controls are so important, the least user interaction will cause them to reappear immediately. When this happens, both this flag will be cleared automatically, so that both elements reappear at the same time.

So I simply replaced

View.SYSTEM_UI_FLAG_HIDE_NAVIGATION

with

View.SYSTEM_UI_FLAG_LOW_PROFILE

نصائح أخرى

Do NOT use an onClickListener in this case. It is solved with this code

View contentView = findViewById(R.id.contentLayout);
contentView.setClickable(true);

final GestureDetector clickDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            boolean visible = (mDecorView.getSystemUiVisibility()
                    & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
            if (visible) 
                hideSystemUI();
            else 
                showSystemUI();
            return true;
        }
    });

contentView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return clickDetector.onTouchEvent(event);
        }
    });

and the functions to go/hide the Immersive Full-Screen Mode:

 private void hideSystemUI() {
    mDecorView.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);
}

private void showSystemUI() {
    mDecorView.setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}

I found out about this problem in a video of Roman Nurik here https://developer.android.com/training/system-ui/immersive.html

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top