0
0

More than 1 year has passed since last update.

android:windowLightNavigationBarはAPI level 27だが、View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BARはAPI level 26という罠

Posted at

Android 5以上ではNavigationBarの色を指定することができます。
テーマではandroid:navigationBarColorで指定しますね。
ただし、ナビゲーションバーのボタンは白系統の色で描画されるため、明るい色を使いたい場合は、android:windowLightNavigationBarをtrueにすることでナビゲーションバーのアイコンが黒系の色に変わり視認性を確保することができます。

<style name="Theme.MyApplication" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
    <item name="android:navigationBarColor">@color/white</item>
    <item name="android:windowLightNavigationBar">true</item>
</style>

この、android:windowLightNavigationBarはAPI level 27なのでAndroid 8.1以上でしか使えません。

Android 8以下では明るい色のナビゲーションバーは諦める必要がありますね。

ナビゲーションバーのアイコンを黒系の色に変更する方法はもう一つあって、View.setSystemUiVisibility()でView.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BARフラグをたてることでも変更できます。
このView.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BARはAPI level 26なのです。

View.setSystemUiVisibility()はDeprecatedなので、制御する場合は、WindowInsetsControllerCompatを使ったりしますよね。

val controller = WindowInsetsControllerCompat(window, binding.root)
controller.isAppearanceLightNavigationBars = true

WindowInsetsControllerCompatの実装はAPI26以上で別れています。

WindowInsetsControllerCompat.java
public WindowInsetsControllerCompat(@NonNull Window window, @NonNull View view) {
    if (SDK_INT >= 30) {
        mImpl = new Impl30(window, this);
    } else if (SDK_INT >= 26) {
        mImpl = new Impl26(window, view);
    } else if (SDK_INT >= 23) {
        mImpl = new Impl23(window, view);
    } else if (SDK_INT >= 20) {
        mImpl = new Impl20(window, view);
    } else {
        mImpl = new Impl();
    }
}

API 26以上でAppearanceLightNavigationBarsの制御が行われます。

@RequiresApi(26)
private static class Impl26 extends Impl23 {

    Impl26(@NonNull Window window, @Nullable View view) {
        super(window, view);
    }

    @Override
    public boolean isAppearanceLightNavigationBars() {
        return (mWindow.getDecorView().getSystemUiVisibility()
                & View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR) != 0;
    }

    @Override
    public void setAppearanceLightNavigationBars(boolean isLight) {
        if (isLight) {
            unsetWindowFlag(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            setWindowFlag(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            setSystemUiFlag(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
        } else {
            unsetSystemUiFlag(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
        }
    }
}

テーマパラメータとしてAPI 27だから26ではNO OPになってくれると期待で使ってしまうと、黒背景に黒アイコンという状態になってしまいます。注意しましょうというお話でした。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0