Immersive mode navigation becomes sticky after volume press or minimise-restore

后端 未结 3 1921
执念已碎
执念已碎 2020-11-28 04:14
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        this.getWindow().getDecorView().setSyste         


        
3条回答
  •  北海茫月
    2020-11-28 04:58

    I had the same problem, and I solved it with a simple workaround. Even though I couldn't find the theoretical reason of this workaround, but it worked for me anyway.

    It seems like when a volume button is pressed, the 'flags' related to the 'immersive mode' are cleared. And I think that's why the immersive mode is disabled and the immersive mode is not restored automatically.

    Therefore, I tried to set the 'flags' after pressing the volume button with 'runnable' object.

    So, it works like this:

    immersive mode -> volume button pressed(flags cleared) -> 500ms later, the runnable object sets the flags again -> immersive mode restored

    1. First, define the runnable object to set the flags

    private Runnable decor_view_settings = new Runnable()
    {
        public void run() 
        {
            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);
        }
    };
    

    2. Post the runnable object with some delay to a handler when a volume button is pressed

    private Handler mHandler = new Handler();
    

    ...

    @Override 
    public boolean onKeyDown(int keyCode, KeyEvent event) 
    {
        if(keyCode == KeyEvent.KEYCODE_BACK)
        {
            finish();
        }
        else if(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP)
        {
            mHandler.postDelayed(decor_view_settings, 500);
        }
    
        return super.onKeyDown(keyCode, event);
    }
    

    I just delayed it for 500ms with no reason, it's not important.

    3. The basic code for immersive mode with runnable object

    @Override
    public void onWindowFocusChanged(boolean hasFocus) 
    {
        super.onWindowFocusChanged(hasFocus);
    
        if(hasFocus) 
        {
            mHandler.post(decor_view_settings);
        }
    }
    

    It worked perfectly on my app.

    So, when I press a volume button, the immersive mode is disabled and the volume rocker pops up.

    after a few seconds, the volume rocker disappears and so does the status bar and the navigation bar.

    Hope this work for you.

提交回复
热议问题