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

View.SYSTEM_UI_FLAG_VISIBLEView.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);
    }
}