Flutterのtheme

Flutter/Dart

この記事では、Flutterのthemeについて書いていきます。

themeとは

アプリの色やテキストの大きさ・フォント・ボタンの形状を統一し長々と色などを指定する手間を省くことができるウィジェットです。

ThemeDataクラスを利用しMaterialAppにデータを渡します。

以下によく使用されるMaterialDesain3の大枠のカテゴリーをまとめました。

Primaryの4つの色役割

プロパティ名役割
primaryアプリの主色(AppBar、メインボタン、強調アイコンなど)
onPrimaryprimary の上に配置する文字やアイコンの色(読みやすいコントラストが自動選択)
primaryContainerカードやコンテナなど、面で主張したいときの背景色
onPrimaryContainerprimaryContainer の上に配置する文字やアイコンの色

Secondaryの4つの色役割

プロパティ名役割
secondary補助的なUI要素(フィルタチップ、選択状態のハイライトなど)
onSecondarysecondary の上に配置する文字やアイコンの色
secondaryContainerPrimaryより目立たせたくない面やカード、FABの背景色
onSecondaryContainersecondaryContainer の上に配置する文字やアイコンの色

Errorの4つの色役割

プロパティ名役割主な使用場所
errorエラーや危険な状態を示す強調色入力エラー枠、削除ボタン、エラー用アイコンなど
onErrorerror の上に配置する文字・アイコン色error 色のボタン上の文字・アイコン
errorContainerエラーメッセージなどの背景面(少し控えめな赤系)エラーアラートの背景、警告カードの面
onErrorContainererrorContainer の上に配置する文字・アイコン色errorContainer 内の解説テキスト

Surfaceの4つの色役割

プロパティ名役割主な使用場所
surface画面全体の基本となる背景色Scaffold の背景、ダイアログのベース面
onSurfacesurface の上に配置する基本テキスト・アイコン色メインの文章、見出し、アクティブなアイコン
surfaceContainer背景と区別して浮かせるカードやエリアの面Card の背景、ボトムシート、リスト項目
onSurfaceVariant少し目立たせたくない(補足的な)テキスト・アイコン色サブタイトル

サンプル

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,

      // --- ここでアプリ全体の色(テーマ)を決める ---
      theme: ThemeData(
        // ベースとなる色を1つ指定するだけで、アプリ全体の色が自動で統一される
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.orange),
      ),

      home: const MainScreen(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        // theme で決めたテーマカラーを呼び出して背景色にする
        backgroundColor: Theme.of(context).colorScheme.primaryContainer,
        title: const Text('Theme の基本デモ'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {},
          child: const Text('ボタンも自動でテーマ色になる'),
        ),
      ),
    );
  }
}

サンプル

TextThereを使ったサンプルです。

サンプルは13行目です。

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // アプリ全体のテキストスタイルを定義
      theme: ThemeData(
        textTheme: const TextTheme(
          headlineLarge: TextStyle(fontSize: 32, fontWeight: FontWeight.bold),
          bodyMedium: TextStyle(fontSize: 16, color: Colors.black87),
        ),
      ),
      home: const HomeScreen(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    // テーマから textTheme を取得
    final textTheme = Theme.of(context).textTheme;

    return Scaffold(
      appBar: AppBar(title: const Text('TextTheme サンプル')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // headlineLarge(大見出し)を適用
            Text('大見出し', style: textTheme.headlineLarge),

            const SizedBox(height: 12),

            // bodyMedium(標準の本文)を適用
            Text('これは標準サイズの本文テキストです。', style: textTheme.bodyMedium),
          ],
        ),
      ),
    );
  }
}
タイトルとURLをコピーしました