LoginSignup
9
2

[Delphi] Android のダークモードに対応する方法

Last updated at Posted at 2023-11-30

Delphi はダークモードに対応していない

Delphi はスタイルで見た目をコントロールしているので、ダーク系のスタイルにすればダークモードになるよ、などと一部の記事に書いてありますが、それは残念ながら嘘です。
スタイルでダーク系の色になるのと、ダークモードの対応は全く別の話です。

↓下記の画像はダークモードが有効な端末でダーク系のスタイルにした所です。
ナビゲーションバーが白背景になっています。

image.png

↓これはデフォルトのカメラのナビゲーションバーです
ちゃんとダークモードの色(黒背景)になっています。

image.png

テーマ

Android ではアプリケーション全体の色調をテーマで指定します。
具体的には styles.xml で↓下のように指定します(parent(継承元)に Android の規定のテーマを指定)。

<style name="AppTheme" parent="@android:style/Theme.Material.Light.NoActionBar">

なお、上記の XML は Delphi が生成したものです。
parent に思いっきり Light が付いているテーマが書いてあります。
これはライトモード用の背景です。
OMG!

生成される styles.xml のテーマを指定できるようになっていれば良いのですが、これを制御する方法は無いようでした(TitleBar の有無だけ指定できます。知っている方が居たら教えてください)。

Delphi でダークモードを指定する

上記の styles.xml ですが実際には下記の3ファイルが生成されます。

  • styles.xml
  • styles-v21.xml
  • styles-v31.xml

Android のバージョンに応じて、このどれかが使われます。
v21, v31 は上記の Light テーマが使われる設定になっているので、これらが使われるとナビゲーションバーが白くなってしまいます。

かといって、styles.xml はビルド時に上書きで自動生成されるため、中身を変えるのは面倒です。
そこで、styles.xml を使わず強制的にテーマを指定してしまうのが最も簡単です。
AndroidManifest.template.xml の中身を書き換えます。

    <application
        中略
        android:theme="%theme%" ←これを
        中略
    <application
        中略
        android:theme="@android:style/Theme.NoTitleBar" ←こう!
        中略

このように色指定の無いテーマを直接指定してしまえば、自動的にシステムの色でナビゲーションバーが表示されます。

image.png

背景色と合致していませんが、これで一応は言い訳が立ちます。

もっとちゃんとやる

背景色と合致してないのかっっこ悪い。
そこで、先ほど面倒と言った事をやります。

まず styles-v31.xml をプロジェクトと同じ場所に作ります。
中身は以下の通りです。

styles-v31.xml
<resources xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Theme.Material テーマはダークモードのテーマ -->
    <style name="AppTheme" parent="@android:style/Theme.Material.NoActionBar">
        <!-- 色指定 -->
        <item name="android:navigationBarColor">ここに色を指定</item>
        <item name="android:navigationBarDividerColor">ここに色を指定</item>
        <item name="android:statusBarColor">ここに色を指定</item>
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <!-- ここから下はオリジナル -->
        <item name="android:windowBackground">@color/splash_background</item>
        <item name="android:windowClipToOutline">false</item>
        <!-- API 31+ specific attributes -->
        <item name="android:windowSplashScreenBackground">@color/splash_background</item>
        <item name="android:windowSplashScreenAnimatedIcon">@drawable/splash_vector</item>
        <item name="android:windowSplashScreenIconBackgroundColor">@color/splash_background</item>
    </style>
</resources>

「ここに色を指定」と書いてある場所(3箇所)は #ffffff という16進数表記や colors.xml の @color で指定します。

色指定について簡単に解説すると下のようになります。

Item 名 意味
navigationBarColor ナビゲーションバーの背景色
navigationBarDividerColor ナビゲーションバーの境界線の色
statusBarColor ステータスバーの背景色

今回はスタイルの背景色と同じ #3c3c3c としました。

この styles-v31.xml を配置マネージャを使ってアプリケーションに含ませます。
配置マネージャを開くと↓このようにデフォルトの styles-v31.xml が登録されているので、これを自作の styles-v31.xml に変更します。

image.png

  1. 自作の styles-v31.xml を配置マネージャに追加します
  2. 元の styles-v31.xml のチェックを外します。
  3. 自作の styles-v31.xml の情報を以下のように変更します。
    リモートパス: res\value-v31\
    リモート名: styles.xml
    設定し終わった画面が下図になります。

image.png

必要であれば styles-v21.xml も同じように指定してください。

これで、ビルドすると styles-v31.xml が上書きされて背景色がそろったキレイな表示になります…が…

image.png

↓下のように線がきえない事もあります!(NavigationBarDivider の色がおかしい)

image.png

Android が自動的に scrim と呼ばれる半透明の帯を被せてくる場合があるためです。
scrim をかけてくるかどうかは、NavigationBar の色によります(ユーザーから見てナビゲーションボタンが見えないとシステムが判断すると scrim をかけてきます)。
scrim を勝手にかけないフラグなどがあるのですが、上手く行きませんでした。
(目では解りづらいですがナビゲーションバーの色も暗くなっています)

いっそのこと、↓こんな風に線に色をつけてしまうのもありかもしれません。

image.png

なお、線の色として #00ffff を指定したのですが、scrim のせいで表示された色は #75fbfd になっていました。

ちなみに、ナビゲーションバーは透過させることができるので、それを使うと NavigationBarDivider は表示されなくなり、この問題は発生しません。
ですが、ナビゲーションバーの裏側までアプリが潜り込むので Margins などを使ってナビゲーションバーに被らないようにしないといけません。

まとめ

楽にやる方法

AndroidManifest.template.xml の android:theme"@android:style/Theme.NoTitleBar" に書き換える。

ちゃんとやる方法

自前の styles-v31.xml (必要であれば styles-v21.xml も)を用意して配置マネージャで置き換える。
線が表示されてしまう場合は、思い切って線に色を付けちゃう。

9
2
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
9
2