【テーマ設計】黒背景・赤アクセント・白文字で動画アプリ風の世界観を作る
この節で学ぶこと
前の節では、アプリ起動時に表示されるスプラッシュ画面を確認しました。
今回の節では、アプリ全体の見た目を決める テーマ設計 について学びます。
今回作っている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などが、どのようにひとまとまりのデータとして管理されているのかを確認します。
次は、画面に表示する「作品データの設計図」を学んでいきましょう。
