ステータスバーのテキストと背景色を変更する最も簡単な方法

質問

Android のステータス バー (StatusBar) の背景色は開発者が変更できることはわかっていますが、テキストの色については、色の値を自分で直接変更することはできませんが、Light と 2 つのグローバル テーマに対応する白と黒です。ダークモデル。

優れたユーザー エクスペリエンスを実現するには、ステータス バーの背景が暗い場合は白いフォントを表示する必要があり、その逆の場合も同様です。例えば:

ここに画像の説明を挿入

ただし、ライト モードでは黒いフォントが必要ない場合があるため、手動で変更する必要があります。

方法

以前は、ステータス バーに関連するコンテンツを変更して、さまざまな反映コードやさまざまなパッケージ化された StatusBarUtils を探していましたが、コードが洗練されていないだけでなく、奇妙な互換性の問題が発生しやすく、メンテナンスに役立ちませんでした。

現在、Google 関係者は、すべてが AndroidX にあるという解決策を提供しています。コードを直接見てください。

import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsControllerCompat;

public class MainActivity extends BaseActivity {
    
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 修改状态栏字体颜色,用AndroidX官方兼容API
        WindowInsetsControllerCompat wic = ViewCompat.getWindowInsetsController(getWindow().getDecorView());
        if (wic != null) {
    
    
            // true表示Light Mode,状态栏字体呈黑色,反之呈白色
            wic.setAppearanceLightStatusBars(false);
        }

        // 修改状态栏背景颜色,还是通用API,这个比较简单
        getWindow().setStatusBarColor(...);
    }
}

拡張すると、下部のナビゲーション バーの変更も含めて、同様になります。

// 修改导航栏按钮颜色
wic.setAppearanceLightNavigationBars(false);
// 修改导航栏背景色
getWindow().setNavigationBarColor();

他の

このクラスを使用するにはWindowInsetsControllerCompat、それをインポートするだけでよくandroidx.core、バージョン番号は任意で、最新のものが使用されます。

androidx.appcompatただし、すでにまたはに依存している場合はcom.google.android.material、最初の 2 つにすでにコアが含まれているため、コアを個別に導入する必要はありません。

dependencies {
    
    
    // 直接依赖
    implementation "androidx.core:core:1.5.0"
    // 间接依赖
    implementation "androidx.appcompat:appcompat:1.3.1"
    // or
    implementation "com.google.android.material:material:1.4.0"
}

実際、興味があれば、ソース コードを確認するだけで済みます。まず、対応する実装が、さまざまなシステム バージョン番号に従って返されます。

@Nullable
public static WindowInsetsControllerCompat getWindowInsetsController(@NonNull View view) {
    
    
    if (Build.VERSION.SDK_INT >= 30) {
    
    
        return ViewCompat.Api30Impl.getWindowInsetsController(view);
    } else {
    
    
        Context context = view.getContext();
        while (context instanceof ContextWrapper) {
    
    
            if (context instanceof Activity) {
    
    
                Window window = ((Activity) context).getWindow();
                return window != null ? WindowCompat.getInsetsController(window, view) : null;
            }
            context = ((ContextWrapper) context).getBaseContext();
        }
        return null;
    }
}

次に、対応するバージョンに従って、対応する実装インターフェイスを呼び出します。

private static class Impl {
    
    
    Impl() {
    
    
        //privatex
    }

    // ... 省略其他

    public boolean isAppearanceLightStatusBars() {
    
    
        return false;
    }

    public void setAppearanceLightStatusBars(boolean isLight) {
    
    
    }

    public boolean isAppearanceLightNavigationBars() {
    
    
        return false;
    }

    public void setAppearanceLightNavigationBars(boolean isLight) {
    
    
    }
}

@RequiresApi(20)
private static class Impl20 extends Impl {
    
    ...}

@RequiresApi(23)
private static class Impl23 extends Impl20 {
    
    ...}

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

@RequiresApi(30)
private static class Impl30 extends Impl {
    
    ...}

これが、開発者が互換性の問題を心配することなく、このクラスがさまざまなバージョンと互換性を持ち、断片化を効果的に軽減できる理由です。たとえば、API 26 より前では、API 26 は継承され、世代間で互換性がありましたが、API 30 ではインターフェイスが再実装されており、30 でいくつかの大きな変更と最適化が行われたことがわかります。

おすすめ

転載: blog.csdn.net/ysy950803/article/details/119869625