Flutterアプリケーション開発概論

【テーマ設計】黒背景・赤アクセント・白文字で動画アプリ風の世界観を作る

6NETFLIX風動画アプリを作りながらUI・検索・動画再生・共有機能を学ぶFlutter(iOS・Android)アプリ開発
FlutteriOSAndroidMacOSWindows基礎から学ぶ開発アプリ開発

この節で学ぶこと

前の節では、アプリ起動時に表示されるスプラッシュ画面を確認しました。

今回の節では、アプリ全体の見た目を決める テーマ設計 について学びます。

今回作っているNETFLIX風アプリは、黒い背景、赤いアクセント、白い文字を中心にしたデザインです。

画面を見たときに、

動画アプリっぽい
映画アプリっぽい
少しリッチに見える
夜に見るアプリっぽい

と感じるのは、色の使い方が大きく関係しています。

アプリ開発では、ボタンや画像を並べるだけではなく、どんな色を使うかどこを目立たせるか文字をどれくらい読みやすくするか がとても大切です。

この節では、今回のアプリで使っている色の管理方法と、アプリ全体のテーマ設定を見ていきます。


今回のアプリのデザイン方針

今回のNETFLIX風アプリでは、全体の雰囲気を次のように作っています。

要素使い方
黒背景動画アプリらしい没入感を出す
白文字黒背景の上でも読みやすくする
赤アクセント重要なボタンやブランド感を出す
グレー補足情報や控えめな文字に使う
画像作品の世界観を伝える

この中で特に大切なのが、黒・白・赤の3色です。

黒:背景
白:文字
赤:強調

この役割がはっきりしているので、画面全体がまとまって見えます。


ThemeDataとは?

Flutterでは、アプリ全体の見た目をまとめて設定するために ThemeData を使います。

今回のコードでは、NetflixLikeApp の中でテーマを作っています。

class NetflixLikeApp extends StatelessWidget {
  const NetflixLikeApp({super.key});

  @override
  Widget build(BuildContext context) {
    final baseTheme = ThemeData(
      useMaterial3: true,
      brightness: Brightness.dark,
      scaffoldBackgroundColor: NetflixColors.black,
      colorScheme: ColorScheme.fromSeed(
        seedColor: NetflixColors.red,
        brightness: Brightness.dark,
      ),
    );

    return MaterialApp(
      title: 'NETAFLIX',
      debugShowCheckedModeBanner: false,
      theme: baseTheme.copyWith(
        textTheme: GoogleFonts.notoSansTextTheme(baseTheme.textTheme),
      ),
      home: const SplashScreen(),
    );
  }
}

少し長く見えますが、やっていることはシンプルです。

アプリ全体を暗いテーマにする
背景色を黒にする
赤をアクセントカラーにする
文字フォントを整える
最初にSplashScreenを表示する

という設定をしています。


brightness: Brightness.dark

まず見てほしいのは、この部分です。

brightness: Brightness.dark,

これは、アプリ全体をダークテーマとして扱う設定です。

ダークテーマにすると、Flutter側も「このアプリは暗い背景を使うんだな」と判断します。

そのため、ボタンや入力欄などの初期状態も、暗い画面に合いやすくなります。

今回のような動画アプリ風UIでは、明るい背景よりも黒背景の方が雰囲気を作りやすいです。


scaffoldBackgroundColorで背景を黒にする

次に、この部分です。

scaffoldBackgroundColor: NetflixColors.black,

Scaffold は、Flutterで画面の土台になるWidgetです。

つまり、scaffoldBackgroundColor は、多くの画面の基本背景色になります。

今回のアプリでは、ほぼすべての画面で黒背景を使いたいので、ここで黒を指定しています。

もちろん、それぞれの画面でも次のように指定しています。

return Scaffold(
  backgroundColor: NetflixColors.black,
  body: ...
);

同じような指定が何度か出てくるのは、「この画面は確実に黒背景にしたい」という意図があるためです。


colorScheme.fromSeedとは?

次に、この部分を見てみましょう。

colorScheme: ColorScheme.fromSeed(
  seedColor: NetflixColors.red,
  brightness: Brightness.dark,
),

ColorScheme は、アプリ内で使う色のまとまりです。

fromSeed は、指定した色をもとに、Flutterが関連する色を作ってくれる仕組みです。

今回の場合は、

seedColor: NetflixColors.red,

なので、赤を基準にした色のまとまりを作っています。

ただし、今回のアプリでは、NetflixColorsで細かく色を管理しているので、ColorScheme はあくまでFlutterの基本テーマを整える役割として使っています。


NetflixColorsで色をまとめる

今回のコードでは、色を直接あちこちに書かず、NetflixColors というクラスにまとめています。

class NetflixColors {
  static const Color black = Color(0xFF000000);
  static const Color deepBlack = Color(0xFF050505);
  static const Color cardBlack = Color(0xFF141414);
  static const Color red = Color(0xFFE50914);
  static const Color white = Color(0xFFFFFFFF);
  static const Color muted = Color(0xFF9A9A9A);
  static const Color darkGray = Color(0xFF222222);
  static const Color navGray = Color(0xCC1E1E1E);
  static const Color chip = Color(0xFF2A2A2A);
}

これは、アプリ内で使う色の一覧表のようなものです。

たとえば、赤色を使いたいときは、毎回このように書きます。

NetflixColors.red

白色を使いたいときは、こうです。

NetflixColors.white

このようにまとめておくと、アプリ全体の色を管理しやすくなります。


なぜ色をまとめるの?

たとえば、コードのいろいろな場所に直接赤色を書いていたとします。

Color(0xFFE50914)

この赤を少し暗くしたくなった場合、コード全体からこの色を探して、全部変更する必要があります。

でも、NetflixColors.red にまとめておけば、ここだけ変更すればOKです。

static const Color red = Color(0xFFE50914);

たとえば、少し落ち着いた赤にしたい場合は、こう変えます。

static const Color red = Color(0xFFB20710);

すると、NetflixColors.red を使っている場所がまとめて変わります。

色をまとめることは、あとからカスタマイズしやすくするためにも大切です。


Color(0xFFE50914)の意味

色は次のように書かれています。

Color(0xFFE50914)

少し暗号のように見えますが、これは色を16進数で指定しています。

0xFF の後に、赤・緑・青の情報が入っています。

0xFF E5 09 14

ざっくり見ると、次のような意味です。

部分意味
FF透明ではなく、しっかり表示する
E5赤の強さ
09緑の強さ
14青の強さ

最初は細かく覚えなくて大丈夫です。

Webデザインやアプリデザインでよく見る、

#E50914

という色を、Flutterでは次のように書くと思ってください。

Color(0xFFE50914)

黒背景が作る雰囲気

今回のアプリでは、背景に黒を多く使っています。

static const Color black = Color(0xFF000000);

黒背景にすると、画面全体が引き締まって見えます。

また、映画や動画のサムネイル画像が目立ちやすくなります。

動画アプリでは、画面そのものよりも、作品の画像や動画を主役にしたい場面が多いです。

そのため、背景は黒くして、余計な主張をしないようにしています。


白文字で読みやすくする

黒背景の上では、白文字がよく読めます。

今回のコードでも、タイトルや重要な文字には白を使っています。

color: NetflixColors.white,

たとえば、Home画面のタイトルはこのような指定になっています。

Text(
  hero.title.toUpperCase(),
  textAlign: TextAlign.center,
  style: const TextStyle(
    color: NetflixColors.white,
    fontSize: 30,
    fontWeight: FontWeight.w900,
    letterSpacing: 2.4,
    height: 1.05,
  ),
),

ここでは、白文字に加えて、太さや文字間も調整しています。

大きなタイトルは、ただ表示するだけでなく、「見出しらしく見える」ように設定しています。


グレーで情報の強さを調整する

すべての文字を白にすると、画面が少しうるさく見えることがあります。

そこで、補足情報や少し控えめに見せたい文字にはグレーを使います。

static const Color muted = Color(0xFF9A9A9A);

たとえば、下部ナビゲーションで選択されていないタブは、白ではなくグレーになっています。

color: selected ? NetflixColors.white : NetflixColors.muted,

これは、

選ばれているものは白で目立たせる
選ばれていないものはグレーで控えめにする

という意味です。

このように、色で情報の優先順位を作ることができます。


赤アクセントで大事な場所を目立たせる

今回のアプリでは、赤色を強調色として使っています。

static const Color red = Color(0xFFE50914);

たとえば、Clips画面の丸い再生ボタンに赤を使っています。

Container(
  width: 58,
  height: 58,
  decoration: const BoxDecoration(
    color: NetflixColors.red,
    shape: BoxShape.circle,
  ),
  child: const Icon(
    Icons.play_arrow_rounded,
    color: NetflixColors.white,
    size: 40,
  ),
),

黒い画面の中に赤いボタンがあると、自然と目に入ります。

赤はとても強い色なので、使いすぎると画面がうるさくなります。

今回のように、再生ボタンやラインなど、重要な場所に絞って使うと効果的です。


cardBlackでカードの背景を作る

作品一覧やMy Netaflix画面では、真っ黒ではなく少し明るい黒を使っています。

static const Color cardBlack = Color(0xFF141414);

たとえば、検索結果の背景には cardBlack を使っています。

Container(
  margin: const EdgeInsets.only(bottom: 9),
  color: NetflixColors.cardBlack,
  child: Row(
    children: [
      ...
    ],
  ),
)

真っ黒な背景の上に、少しだけ明るい黒のカードを置くことで、画面に段差ができます。

白い線をたくさん入れなくても、色の差だけで「ここはひとつのまとまりなんだな」と分かります。


darkGrayでボタンや入力欄を作る

darkGray は、ボタンや検索欄などによく使っています。

static const Color darkGray = Color(0xFF222222);

たとえば、Search画面の入力欄では、この色を使っています。

decoration: BoxDecoration(
  color: NetflixColors.darkGray,
  borderRadius: BorderRadius.circular(6),
),

真っ黒より少し明るい色を使うことで、入力欄が画面から浮き上がって見えます。

黒背景のUIでは、このような「黒に近いグレー」をうまく使うことが大切です。


GoogleFontsで文字の雰囲気を整える

今回のアプリでは、Google Fontsも使っています。

theme: baseTheme.copyWith(
  textTheme: GoogleFonts.notoSansTextTheme(baseTheme.textTheme),
),

これは、アプリ全体の文字を Noto Sans 系の見た目にする設定です。

フォントは、アプリの印象をかなり左右します。

たとえば、同じ文字でも、細いフォントなら上品に見えます。

太いフォントなら、力強く見えます。

今回のアプリでは、タイトルやボタンに太めの文字を使い、動画アプリらしい強さを出しています。


TextStyleで文字を細かく調整する

テーマで全体のフォントを決めたあと、必要な場所では TextStyle を使って文字を細かく調整します。

たとえば、作品タイトルはこのように設定されています。

style: const TextStyle(
  color: NetflixColors.white,
  fontSize: 30,
  fontWeight: FontWeight.w900,
  letterSpacing: 2.4,
  height: 1.05,
),

それぞれの意味は次の通りです。

指定意味
color文字色
fontSize文字サイズ
fontWeight文字の太さ
letterSpacing文字と文字の間
height行の高さ

このように、文字の見た目は細かく調整できます。

特に、動画アプリ風のタイトルでは、太く、大きく、少し文字間を広げると雰囲気が出やすいです。


withValues(alpha: 0.72)とは?

コードの中には、次のような書き方があります。

NetflixColors.white.withValues(alpha: 0.72)

これは、白色を少し透明にする指定です。

alpha は透明度のようなものです。

見え方
1.0はっきり表示
0.72少し薄く表示
0.55かなり控えめ
0.0見えない

たとえば、スプラッシュ画面の説明文では、白を少し薄くしています。

color: NetflixColors.white.withValues(alpha: 0.72),

ロゴを主役にしたいので、説明文は少し控えめにしているわけです。

このように、透明度を使うと、文字の強さを調整できます。


グラデーションで画像と文字をなじませる

動画アプリ風UIでは、背景画像の上に文字を重ねる場面が多くあります。

ただし、画像の上にそのまま白文字を置くと、画像によっては読みにくくなります。

そこで使うのが、黒いグラデーションです。

たとえば、Home画面では次のように書いています。

gradient: LinearGradient(
  begin: Alignment.topCenter,
  end: Alignment.bottomCenter,
  colors: [
    NetflixColors.black,
    Colors.black.withValues(alpha: 0.92),
    Colors.black.withValues(alpha: 0.28),
    Colors.black.withValues(alpha: 0.78),
    NetflixColors.black,
  ],
  stops: const [0.0, 0.16, 0.38, 0.78, 1.0],
),

少し難しく見えますが、目的はシンプルです。

画像を暗くして、上に乗る文字を読みやすくする

ということです。

動画アプリ風のUIでは、グラデーションはかなりよく使います。


stopsとは?

グラデーションの中に、次のような指定があります。

stops: const [0.0, 0.16, 0.38, 0.78, 1.0],

これは、どの位置でどの色にするかを決めています。

ざっくり言うと、

0.0 が一番上
1.0 が一番下

です。

つまり、上から下に向かって、黒の強さを変えています。

背景画像の上部や下部を暗くすると、ロゴやボタン、タイトルが読みやすくなります。


テーマ設計で大切な考え方

ここまで見てきたように、テーマ設計は「色をなんとなく決めること」ではありません。

大切なのは、色に役割を持たせることです。

今回のアプリでは、次のように役割を決めています。

役割
背景、没入感
重要な文字
再生ボタン、アクセント
グレー補足情報、未選択状態
少し明るい黒カードや入力欄

このルールがあると、画面がバラバラになりにくくなります。

アプリをカスタマイズするときも、このルールを意識するときれいにまとまります。


まずカスタマイズしてみよう

今回は、赤色を少し落ち着いた色に変えてみます。

次のコードを探してください。

static const Color red = Color(0xFFE50914);

これを、少し深い赤に変えてみます。

static const Color red = Color(0xFFB20710);

保存して、アプリを再起動してください。

Clips画面の赤い再生ボタンや、Episodesの赤いラインの印象が少し変わります。

派手な印象から、少し落ち着いた印象になります。


背景色もカスタマイズしてみよう

次に、完全な黒ではなく、少しだけやわらかい黒にしてみます。

変更前はこちらです。

static const Color black = Color(0xFF000000);

変更後の例です。

static const Color black = Color(0xFF050505);

見た目の差は小さいですが、少しだけやわらかい印象になります。

真っ黒はかっこいい反面、少し強く見えることがあります。

アプリの雰囲気に合わせて調整してみましょう。


文字色をカスタマイズするときの注意

白文字を変更するときは、読みやすさに注意します。

たとえば、黒背景に対して文字を暗いグレーにしすぎると、読みにくくなります。

変更前:

static const Color white = Color(0xFFFFFFFF);

もし少しだけやわらかくしたいなら、完全な白ではなく、少しだけ暗い白にすることもできます。

static const Color white = Color(0xFFF5F5F5);

ただし、文字の読みやすさは大切なので、暗くしすぎないようにしましょう。


よくあるつまずきポイント

Q. 色を変えたのに画面が変わりません。

まず、変更した色が実際に使われているか確認しましょう。

たとえば、NetflixColors.red を変えると、NetflixColors.red を使っている場所だけが変わります。

一方で、コードの中に直接こう書いてある色は変わりません。

const Color(0xFF46D369)

色が変わらないときは、どの色がどこで使われているかを探してみましょう。


Q. withValuesでエラーが出ます。

Flutterの環境によっては、withValues が使えない場合があります。

その場合は、次のように書き換えると動くことがあります。

Colors.black.withOpacity(0.55)

たとえば、変更前がこちらです。

Colors.black.withValues(alpha: 0.55)

変更後はこうです。

Colors.black.withOpacity(0.55)

新しいFlutterでは withValues が使われることがありますが、環境によって違いがあります。

エラーが出たら、慌てずに書き方を合わせましょう。


Q. 画面全体が暗すぎます。

黒背景のUIでは、全部を暗くしすぎると見づらくなることがあります。

その場合は、カードや入力欄の色を少し明るくします。

たとえば、次の色を調整します。

static const Color cardBlack = Color(0xFF141414);
static const Color darkGray = Color(0xFF222222);

少し明るくしたい場合は、こうしてみます。

static const Color cardBlack = Color(0xFF1A1A1A);
static const Color darkGray = Color(0xFF2A2A2A);

少しの差でも、画面の見やすさは変わります。


Q. 赤色が強すぎます。

赤は目立つ色なので、強すぎると感じる場合があります。

その場合は、少し暗い赤に変えてみましょう。

static const Color red = Color(0xFFB20710);

赤の使いどころを減らすのも効果的です。

大事な場所だけ赤にすると、画面にメリハリが出ます。


チャレンジ

チャレンジ1:赤色を落ち着いた赤に変えよう

次のコードを探してください。

static const Color red = Color(0xFFE50914);

これを次のように変えてみましょう。

static const Color red = Color(0xFFB20710);

赤いボタンやラインの印象が変わるか確認してください。


チャレンジ2:背景色を少しやわらかい黒にしよう

次のコードを探してください。

static const Color black = Color(0xFF000000);

これを次のように変えてみましょう。

static const Color black = Color(0xFF050505);

画面全体の雰囲気が少し変わるか確認してみましょう。


チャレンジ3:未選択のタブ色を少し明るくしよう

次のコードを探してください。

static const Color muted = Color(0xFF9A9A9A);

これを次のように変えてみます。

static const Color muted = Color(0xFFB0B0B0);

下部ナビゲーションの未選択タブが少し見やすくなるか確認してください。


チャレンジ4:検索欄の背景色を少し明るくしよう

次のコードを探してください。

static const Color darkGray = Color(0xFF222222);

これを次のように変更します。

static const Color darkGray = Color(0xFF2A2A2A);

Search画面の入力欄やDownloadボタンの見え方が変わります。


チャレンジの答え

チャレンジ1の答え

変更前:

static const Color red = Color(0xFFE50914);

変更後:

static const Color red = Color(0xFFB20710);

赤色が少し落ち着いた印象になります。


チャレンジ2の答え

変更前:

static const Color black = Color(0xFF000000);

変更後:

static const Color black = Color(0xFF050505);

完全な黒より少しだけやわらかい背景になります。


チャレンジ3の答え

変更前:

static const Color muted = Color(0xFF9A9A9A);

変更後:

static const Color muted = Color(0xFFB0B0B0);

未選択のタブや補足テキストが少し見やすくなります。


チャレンジ4の答え

変更前:

static const Color darkGray = Color(0xFF222222);

変更後:

static const Color darkGray = Color(0xFF2A2A2A);

検索欄や一部のボタン背景が少し明るくなります。


この節のまとめ

この節では、NETAFLIX風アプリのテーマ設計を確認しました。

大切なポイントは次の通りです。

  • ThemeData は、アプリ全体の見た目を決めるために使う。
  • Brightness.dark を使うと、暗い画面に合ったテーマになる。
  • scaffoldBackgroundColor で画面の基本背景色を設定できる。
  • NetflixColors に色をまとめると、あとからカスタマイズしやすい。
  • 黒背景は、動画アプリらしい没入感を作る。
  • 白文字は、黒背景の上で読みやすい。
  • 赤は目立つ色なので、重要なボタンやアクセントに使う。
  • グレーは、補足情報や未選択状態に使う。
  • グラデーションを使うと、背景画像の上でも文字が読みやすくなる。
  • 色にはそれぞれ役割を持たせると、画面がまとまりやすい。

次のステップ

次の節では、作品データを管理する MovieItem クラスを見ていきます。

アプリに表示されている作品タイトル、説明文、画像URL、YouTube動画IDなどが、どのようにひとまとまりのデータとして管理されているのかを確認します。

次は、画面に表示する「作品データの設計図」を学んでいきましょう。

教材トップへ戻る