.NET MAUI Androidで全画面に黒帯が出る原因と解決策(SystemBars/Target SDK/AndroidManifest)

.NET MAUIでAndroidアプリを動かすと、上下(または下側)に黒帯が出て「全画面にしたいのに余白が残る」ことがあります。実はこの現象は、システムバーが残っているケースと、Target SDK/AndroidManifestの不整合で互換表示(レターボックス)になっているケースに大別できます。原因の切り分けから、MainActivityの実装例と設定の直し方まで解説します。

目次

よくある症状と「黒帯(黒線)」の正体

.NET MAUI(Android)で「全画面表示にしたいのに上下(または下側)に黒帯・黒線が出る」現象は、見た目が似ていても原因が違うことが多いです。対処を間違えると、MainActivityをいくら弄っても直らない、または特定の端末だけ再発するといった沼に入りやすいので、まずは黒帯の種類を整理します。

黒帯の見え方よくある状況疑うべき原因最初の一手
画面上部/下部に一定の黒い領域が出る。スワイプでバーが出たり消えたりするジェスチャーナビ/3ボタンナビで挙動が変わる。キーボード表示で余白が増減する原因A:ステータスバー/ナビゲーションバー(System Bars)が残っている、Insets制御ができていないMainActivityでWindowInsetsControllerCompatを使い、SystemBarsを隠す(没入型)
アプリ起動直後(スプラッシュ画面の時点)から黒帯が出る。端末やエミュレーターで差がある古いエミュレーターはダメ、新しいエミュレーターはOKなど環境依存が強い原因B:Target SDK/AndroidManifest/SDK設定の不整合で互換表示(レターボックス)になっているTarget SDKを最新寄りにし、Min SDKだけ下げる。生成されたManifestで実際の値を確認する
黒帯というより「ノッチ周辺」「角丸」「ジェスチャー領域」を避けているように見えるノッチ付き端末、縦長端末、タブレットで目立つDisplay Cutout設定、最大アスペクト比、画面回転固定、リサイズ不可などの設定追加チェック項目(後述)を確認する

最短で切り分けるチェックリスト

修正コードを書く前に、次のチェックで原因Aか原因Bかをほぼ判定できます。ここで迷わないと、解決までが一気に早くなります。

チェック項目見え方/結果判断
黒帯はスプラッシュ画面の時点で出ている?出ている原因B寄り(Activityより前の設定が疑わしい)
画面下端をスワイプするとナビゲーションバーが一時表示される?表示される/消える原因A寄り(System Barsの制御で改善する可能性が高い)
端末/エミュレーターのAPIレベルで再現が変わる?古い/新しいで挙動が変わる原因B寄り(Target SDKや互換モードの影響)
黒帯部分に時計/電波/戻るボタンなどのUIが載っている?載っている原因A寄り(ステータスバー/ナビゲーションバーそのもの)
黒帯部分は完全な真っ黒で、UIが一切ない(ただの余白)?余白のみ原因Bまたはテーマ/背景色の可能性(Aの「透明化」不足もあり得る)

原因A:システムバーが残っていて“全画面化できていない”

Androidでの「全画面」は、単にレイアウトを画面いっぱいに広げるだけでは成立しません。ステータスバーやナビゲーションバーは、端末の操作性や安全性のために表示され続けることが多く、アプリ側がInsets(余白)を正しく扱わないと、コンテンツが「システムバーの外側」に留まって黒帯のように見えます。

ポイントは「Insetsの制御」+「System Barsの非表示」

  • WindowCompat.SetDecorFitsSystemWindows(Window, false):コンテンツをシステムウィンドウに“合わせない”(=コンテンツを端まで伸ばせる)
  • WindowInsetsControllerCompatでSystemBarsを隠す:ステータスバー/ナビゲーションバーを非表示にする
  • SystemBarsBehaviorを設定:スワイプ時だけ一時表示できるようにする(没入型に近い使い心地)

MainActivity.cs の実装例(.NET MAUI / Android)

以下は、.NET MAUIの MainActivity : MauiAppCompatActivity で「没入型表示」を行う代表例です。起動直後のタイミングで一度適用し、必要ならフォーカス復帰でも再適用すると安定します。

using Android.App;
using Android.OS;
using AndroidX.Core.View;

namespace YourAppNamespace;

[Activity(
    Theme = "@style/Maui.SplashTheme",
    MainLauncher = true,
    ConfigurationChanges =
        Android.Content.PM.ConfigChanges.ScreenSize |
        Android.Content.PM.ConfigChanges.Orientation |
        Android.Content.PM.ConfigChanges.UiMode |
        Android.Content.PM.ConfigChanges.ScreenLayout |
        Android.Content.PM.ConfigChanges.SmallestScreenSize)]
public class MainActivity : MauiAppCompatActivity
{
    protected override void OnCreate(Bundle? savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        ApplyImmersiveMode();
    }

    public override void OnWindowFocusChanged(bool hasFocus)
    {
        base.OnWindowFocusChanged(hasFocus);
        if (hasFocus) ApplyImmersiveMode();
    }

    void ApplyImmersiveMode()
    {
        // 1) コンテンツをシステムバー領域まで伸ばす(Edge-to-edge)
        WindowCompat.SetDecorFitsSystemWindows(Window, false);

        // 2) System Bars を非表示にする(没入型)
        var controller = WindowCompat.GetInsetsController(Window, Window.DecorView);
        if (controller is null) return;

        controller.Hide(WindowInsetsCompat.Type.SystemBars());

        // 3) 必要時だけスワイプで一時表示できる挙動にする
        controller.SystemBarsBehavior =
            WindowInsetsControllerCompat.BehaviorShowTransientBarsBySwipe;
    }
}

「黒帯」というよりステータスバー/ナビゲーションバーの背景が黒く見えているだけなら、隠す代わりに透過させる(または色を指定する)アプローチも有効です。ただし、端末やAndroidバージョンで見え方が変わりやすいので、まずは上の手順で「本当に全画面化できているか」を確認するのが安全です。

黒帯が“戻る”ときの考え方

Androidは、画面回転・キーボード表示・ダイアログ表示・別アプリから戻るなどのタイミングでSystem Barsの状態が変わることがあります。その結果、起動時は消えても操作中に黒帯が復活する場合があります。

このときは、上記のように OnWindowFocusChanged で再適用するか、アプリの状態遷移に合わせて(例:OnResume)再適用することで安定します。逆に、常にSystem Barsを消すのがUX的に厳しいアプリ(フォーム入力中心など)では、「隠す」ではなく「色/透明度を調整して違和感を減らす」方が現実的な場合もあります。

テーマ側で「黒く見える」原因を潰す

System Barsを消さない場合や、端末によってはバー領域に背景色が塗られて「黒帯」に見える場合があります。これはThemeの設定で改善できることがあります。

<!-- Platforms/Android/Resources/values/styles.xml の例 -->
<resources>

  <!-- スプラッシュ用テーマ(起動直後の黒帯/チラつきもここが関係します) -->
  <style name="Maui.SplashTheme" parent="Theme.SplashScreen">
    <item name="android:statusBarColor">@android:color/transparent</item>
    <item name="android:navigationBarColor">@android:color/transparent</item>
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
  </style>

  <!-- 通常表示用テーマ -->
  <style name="Maui.MainTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
    <item name="android:statusBarColor">@android:color/transparent</item>
    <item name="android:navigationBarColor">@android:color/transparent</item>
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
  </style>

</resources>

注意点として、透過にした場合はコンテンツがバー領域に被るため、画面上部/下部のUIが見切れないようにレイアウト側でInsetsを考慮する必要があります。「全画面=何も考えなくていい」ではなく、全画面にした分だけUI配置の設計が必要、というイメージです。

原因Aでよくある落とし穴

落とし穴症状対策
古いフルスクリーンAPI(Flags)だけで頑張る一部端末/ジェスチャーナビで効かない、すぐ戻るWindowInsetsControllerCompat(AndroidX)を優先し、必要ならフォーカス復帰で再適用
SetDecorFitsSystemWindowsの設定がないバーを消してもコンテンツが端まで伸びないSetDecorFitsSystemWindows(false) を併用してEdge-to-edgeにする
テーマのstatusBarColor/navigationBarColorが黒のまま「バーが残って黒帯に見える」テーマで色を指定(透明/アプリ色など)。ただしコンテンツの見切れに注意
フォーカス復帰時に再適用していない一度は消えるが、戻る操作や画面回転で再出現OnWindowFocusChanged/OnResume等で再適用する

原因B:“MainActivityが動く前から”黒帯が見える/端末・エミュレーターで挙動が違う

こちらは、コードでSystem Barsを制御する以前に、アプリが互換モード(レターボックス)のような表示になっているパターンです。特に「Android 5.0(API 21)をターゲットしていた」「Android 10以上のエミュレーターだとおかしい(または逆)」のように、環境差があるときは原因Bを強く疑います。

なぜTarget SDKが古いと黒帯が出るのか

Androidは、新しい画面仕様(縦長ディスプレイ、ノッチ、角丸、ジェスチャーナビ、マルチウィンドウなど)に対して、古いTarget SDKのアプリが安全に動くように互換動作を行うことがあります。その一環として、アプリの表示領域を意図的に狭めたり、特定領域を使わせないことで、結果的に黒帯(余白)が発生することがあります。

つまりこのケースは、「UIを隠す/透過する」の問題ではなく、「アプリが新しいOSで正しい前提(Target SDK)として扱われていない」のが本質です。

まず確認するべきは「生成されたAndroidManifest.xml」

.NET MAUIは、プロジェクト内の設定(.csprojや手動で追加したAndroidManifestなど)からビルド時に最終的なManifestを生成します。あなたが編集しているAndroidManifest.xmlと、実際に端末へ入るManifestがズレていることもあります。

  • ビルド後に obj/Debug/net8.0-android/AndroidManifest.xml(構成によりReleaseなど)を開いて、targetSdkVersion と minSdkVersion を確認する
  • 「手動のAndroidManifestを置いている場合」は、<uses-sdk> の指定が古く固定されていないか確認する

推奨方針:Target SDKは最新寄り、Min SDKで下限を担保

古いOSをサポートしたい場合でも、基本はMin SDKで下限を決め、Target SDKはできるだけ新しく保ちます。これにより、新しいAndroidで互換モードに入るリスクを下げられます。

項目役割おすすめよくある失敗
Min SDK(minSdkVersion)インストールできる最小OS要件に合わせて下げる(例:Android 5.0相当のAPI 21)必要以上に上げてしまい、古い端末が切り捨てになる
Target SDK(targetSdkVersion)アプリが想定するOSの挙動最新寄り(例:検証しているAndroidの主要バージョン相当)Min SDKと混同して低く固定し、互換動作でレイアウトが崩れる
エミュレーターAPIレベル検証環境Min/Target/実運用想定に合わせて複数用意検証したいOSとズレたAVDだけで判断してしまう

.csprojで設定する例(.NET MAUI)

MAUIプロジェクトでは、AndroidのMin/Targetをプロジェクト設定で管理できます。チーム開発やCIでもブレにくいので、まずはここを整えるのが手堅いです(プロパティ名は利用している.NET/Androidワークロードで差が出る場合があります)。

<PropertyGroup>
  <TargetFrameworks>net8.0-android;net8.0-ios;net8.0-maccatalyst</TargetFrameworks>

  <!-- 最小対応(例:Android 5.0 / API 21) -->
  <AndroidMinSdkVersion>21</AndroidMinSdkVersion>

  <!-- ターゲットは最新寄り(例:API 34) -->
  <AndroidTargetSdkVersion>34</AndroidTargetSdkVersion>
</PropertyGroup>

もしプロジェクト内にAndroidManifest.xmlを手動で置いているなら、<uses-sdk> でTargetを古く固定していないか要注意です。MAUI側の設定とManifest側の設定が食い違うと、「実機はOKだがエミュレーターはNG」のようなブレが起きやすくなります。

AndroidManifest.xmlを自前管理している場合の注意

手動のAndroidManifestに以下のような指定がある場合、意図せず古いTarget SDKとして扱われることがあります。

<!-- 例:Targetが古く固定されてしまうパターン -->
<uses-sdk
  android:minSdkVersion="21"
  android:targetSdkVersion="21" />

この状態でAndroid 10以降のエミュレーター/実機に入れると、互換動作の影響が強く出て「黒帯が消えない」「端末差が出る」といった現象が起きやすくなります。修正方針は次のどちらかです。

  • Manifestの<uses-sdk>指定を削除し、.csproj側で一元管理する
  • Manifestを残すなら、Min/Targetをプロジェクト設定と同じ値に揃える

エミュレーターでの再現性を上げるコツ

黒帯問題は、検証環境が揃っていないと「直ったのか偶然なのか」が判断しづらいです。おすすめは、APIレベル別にAVDを用意して、どの軸で差が出るかを明確にすることです。

検証対象AVD例見るべきポイント
Min SDK相当API 21〜23起動できるか、画面サイズやノッチがない環境でのベース動作
現行に近いAPI 29〜30(Android 10〜11)ジェスチャーナビ、Insets、スプラッシュから黒帯が出ないか
最新API 33〜34ターゲット互換、Display Cutout、UIの見切れや余白

また、最速の切り分けとして新規のMAUIプロジェクトを作り、同じエミュレーターで表示が正常かを確認するのも有効です。新規プロジェクトで問題が再現しないなら、既存プロジェクトのManifest/テーマ/ターゲット設定に原因が寄っている可能性が高くなります。

それでも黒帯が消えないときの追加チェック

原因A/Bを潰しても残る場合は、端末形状やアクティビティ設定が関係していることがあります。特にノッチ端末・縦長端末・タブレットで目立ちます。

追加チェックありがちな設定起こり得る症状対処の方向性
Display Cutout(ノッチ)cutout領域を使わない既定上端に余白が残る/見切れ回避で黒帯に見えるテーマで android:windowLayoutInDisplayCutoutMode を検討(ただしUI設計とセット)
画面回転固定・リサイズ不可screenOrientation固定、resizeableActivityをfalse一部端末でレターボックス(余白)固定が必要か再検討。必要なら端末差を前提にレイアウト調整
スプラッシュテーマと本テーマの差SplashThemeは黒背景、本テーマは別色起動直後だけ黒帯に見える/切り替わりでチラつくSplashThemeとMainThemeのSystem Bar設定を揃える
背景色が黒のままページ背景、Window背景が黒「余白」が黒帯に見える一時的に背景色を派手な色にして、余白の正体(どのレイヤーか)を特定する

実務で迷わないためのおすすめ手順

最後に、現場で再発しやすい「黒帯問題」を短時間で潰すための手順をまとめます。上から順にやると、遠回りしにくいです。

  1. 黒帯がスプラッシュ時点で出るかを確認し、原因A/Bの当たりを付ける
  2. 原因A疑いなら、MainActivityでInsets制御+SystemBars非表示を入れて挙動を見る
  3. 同時に、テーマのstatusBarColor/navigationBarColorを確認し、黒く見えているだけの可能性を潰す
  4. 原因B疑いなら、生成されたAndroidManifestでMin/Targetを確認し、Target SDKを最新寄りに修正する
  5. APIレベル別にAVDを用意し、どの条件で再現するかを表にして記録する(端末差の説明がしやすくなる)

まとめ

.NET MAUI(Android)の「全画面なのに黒帯が出る」問題は、システムバーが残っている(原因A)のか、Target SDK/Manifestの不整合で互換表示になっている(原因B)のかで、最適解が変わります。まずはスプラッシュ時点の挙動と生成Manifestで切り分け、AならInsets+SystemBars制御、BならTargetを最新寄りに直す――この順で進めれば、コードと設定の両面から最短距離で解決できます。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次