web-dev-qa-db-ja.com

没入モードナビゲーションは、ボリュームプレスまたはminimise-restore後にスティッキーになる

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        this.getWindow().getDecorView().setSystemUiVisibility(getSystemUiFlags());
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    private static int getSystemUiFlags() {
            return View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
    }

}

最初の開始後

After first start

ボリュームボタンを押した後、または最近のアプリを2回押した後

enter image description here

QuickPicアプリにはこのバグがないことがわかりました。彼らはどうやってそれを省略したのだろうか。

28

次のコードは私のために機能します:

public void updateUI() {
    final View decorView = getWindow().getDecorView();
    decorView.setOnSystemUiVisibilityChangeListener (new View.OnSystemUiVisibilityChangeListener() {
        @Override
        public void onSystemUiVisibilityChange(int visibility) {
            if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
                decorView.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);
                }
            }
        });
}

onCreateおよびonResumeメソッドのリスナーを呼び出しました:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    updateUI();
}

@Override
public void onResume() {
    super.onResume();
    updateUI();
}
55
emjee

私の解決策は、UI可視性フラグを3つの場所に設定することです。

  1. フォーカスを取得するとき
  2. OnResumeで
  3. OnSystemUiVisibilityChangeListenerリスナー内

3番目は私の問題を解決しました。他は必要ないかもしれませんが、私はそれらを残しました。これは次のようなものです。

  private void setupMainWindowDisplayMode() {
    View decorView = setSystemUiVisilityMode();
    decorView.setOnSystemUiVisibilityChangeListener(new OnSystemUiVisibilityChangeListener() {
      @Override
      public void onSystemUiVisibilityChange(int visibility) {
        setSystemUiVisilityMode(); // Needed to avoid exiting immersive_sticky when keyboard is displayed
      }
    });
  }

  private View setSystemUiVisilityMode() {
    View decorView = getWindow().getDecorView();
    int options;
    options =
        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_STICKY;

    decorView.setSystemUiVisibility(options);
    return decorView;
  }

setupMainWindowDisplayMode()はonCreate()で呼び出されます。

21
Chris

私も同じ問題を抱えていましたが、簡単な回避策で解決しました。この回避策の理論的な理由はわかりませんでしたが、とにかくうまくいきました。

音量ボタンを押すと、「没入モード」に関連する「フラグ」がクリアされるようです。それが、没入モードが無効になっていて、没入モードが自動的に復元されない理由だと思います。

したがって、「実行可能」オブジェクトで音量ボタンを押した後、「フラグ」を設定しようとしました。

したがって、次のように機能します。

没入モード->音量ボタンが押された(フラグがクリアされた)-> 500ms後、実行可能オブジェクトがフラグを再度設定する->没入モードが復元された

1。最初に、フラグを設定する実行可能オブジェクトを定義します

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。ボリュームボタンが押されたときに、ハンドラーに遅延を伴う実行可能オブジェクトをポストします

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);
}

理由もなく500ミリ秒遅らせただけで、重要ではありません。

。実行可能オブジェクトを使用した没入型モードの基本コード

@Override
public void onWindowFocusChanged(boolean hasFocus) 
{
    super.onWindowFocusChanged(hasFocus);

    if(hasFocus) 
    {
        mHandler.post(decor_view_settings);
    }
}

私のアプリでは完璧に機能しました。

そのため、音量ボタンを押すと、没入モードが無効になり、音量ロッカーがポップアップします。

数秒後、ボリュームロッカーが消え、ステータスバーとナビゲーションバーも消えます。

この仕事があなたのために願っています。

18
Sangseok