417
フルスクリーン（`Immersive Mode`）でコンテンツを表示し、動的にナビゲーションバーの表示・非表示を行うアプリケーションを制作しています。

`View.SYSTEM_UI_FLAG_VISIBLE`と`View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION`でフルスクリーンのままナビゲーションバーをコンテンツ上に出すことはできたのですが、その際にナビゲーションバーの分のパディングを取得する方法がわかりません。

`fitSystemWindows(Rect insets)`を利用する方法を試したところ、取得できる場合と取得できない場合がありました。

```

    @Override
    protected boolean fitSystemWindows(Rect insets) {
        Log.d(getClass().getSimpleName(), "insets="+insets.toShortString());
        return super.fitSystemWindows(insets);
    }
    
```

  * アプリ起動時は取得できる：`insets=[0,75][0,144]`
  * 画面回転・ナビゲーションバー表示切替時は取得できない：`insets=[0,0][0,0]`

この`fitSystemWindows`というメソッドの挙動がいまいちわかりません。 メソッドの使い方が良くないのでしょうか？

また、他に有効な手段をご存じの方がいらっしゃいましたら教えて下さい。

サンプルのコードを添付します。

```

    public class MainActivity extends ActionBarActivity {
    
    private boolean mOverlayMode = false;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setOverlayMode(true);
        setContentView(R.layout.activity_main);
        ButterKnife.inject(this);
    }
    
    @OnClick(R.id.button_overlay)
    void switchOverlayMode() {
        setOverlayMode(!mOverlayMode);
    }
    
    /**
     * ステータスバー・ナビゲーションバーの表示・非表示
     * @param mode
     */
    private void setOverlayMode(boolean mode) {
        mOverlayMode = mode;
    
        Window window = getWindow();
        if (mode) {
            window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            window.addFlags(
                    WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN 
                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                int systemUiVisibility = 
                        View.SYSTEM_UI_FLAG_VISIBLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                    systemUiVisibility |= 
                               View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
                }
                window.getDecorView().setSystemUiVisibility(systemUiVisibility);
            }
        } else {
            window.addFlags(
                    WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN 
                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
                    | WindowManager.LayoutParams.FLAG_FULLSCREEN);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                int systemUiVisibility =
                        View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_LOW_PROFILE
                        | View.SYSTEM_UI_FLAG_FULLSCREEN;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                    systemUiVisibility |= 
                            View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_IMMERSIVE;
                }
                window.getDecorView().setSystemUiVisibility(systemUiVisibility);
            }
        }
    }
    
```

## ■追記

ご回答いただいた方法でうまくいきましたので最終的なコードを載せておきます。

```

    /**
     * フルスクリーン表示時のシステム表示分のパディングを取得する.
     */
    @SuppressLint("NewApi")
    public static Rect getSystemWindowPadding(Activity activity) {
        if (activity == null) { 
            return new Rect();
        }
        final int statusBarHeight = getStatusBarHeight(activity); // ステータスバーの高さを取得。ここでは割愛
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            final Display display = activity.getWindowManager().getDefaultDisplay();
            final Point screenSize = new Point(0, 0);
            final Point windowSize = new Point(0, 0);
            display.getRealSize(screenSize);
            display.getSize(windowSize);
    
            final int paddingBottom = screenSize.y-windowSize.y; // ナビゲーションバーが下に表示される場合
            final int paddingRight  = screenSize.x-windowSize.x; // ナビゲーションバーが右に表示される場合
            return new Rect(0, statusBarHeight, paddingRight, paddingBottom);
        } else {
            return new Rect(0, statusBarHeight, 0, 0);
        }
    }
    
```
CC BY-SA 3.0
2014-12-07T03:09:30.420
415
2019-02-17T01:17:57.963
2014-12-07T14:16:23.200
915
915
question
android
Android KitKatでナビゲーションバーやステータスバーの分のpaddingを取得したい
こちらの手法はいかがでしょうか。

直接ナビゲーションバーを取得する方法ではありませんが、[画面サイズの計算方法](http://techbooster.org/android/hacks/16066/)をまとめたことがあります。  
たとえばナビゲーションバーの高さは、液晶ディスプレイのサイズ（高さ）から表示可能なディスプレイサイズを引くと計算できます（ナビゲーションバーの高さは、機種ごとに異なる可能性があります）。

[![ナビゲーションバーのサイズ計算](https://i.stack.imgur.com/HPlBc.png)](https://i.stack.imgur.com/HPlBc.png)  
(source: [techbooster.org](http://techbooster.org/wp-
content/uploads/2013/02/screensize2.png))

実際にはDisplayクラスのgetRealSize() - getSize() = ナビゲーションバーの高さとして計算しているので、

getRealSizeメソッドで液晶ディスプレイの高さを取得して

```

    Display display = getWindowManager().getDefaultDisplay();
    Point real = new Point(0, 0);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        // Android 4.2以上で対応
        display.getRealSize(real);
    }
    
```

getSizeメソッドで表示領域（Androidアプリとして描画可能な領域）

```

    Display display = getWindowManager().getDefaultDisplay();
    Point p = new Point();
    display.getSize(p);
    
```

これを引き算すると、1280px – 1184px = 96px のようなかたちでナビゲーションバーの高さが取得できます。
CC BY-SA 4.0
2014-12-07T04:32:56.677
417
2019-02-17T01:17:57.963
2019-02-17T01:17:57.963
19769
395
415
answer