【Flutter】TimePickerのテーマをいじってみる

# はじめに
弊社で開発している自社サービスにおいて日付の選択はDatePicker、
時間の選択はTimePickerを使用しています

それぞれにアプリ全体のテーマカラーを適用した際、TimePickerに関しては自由度が高かったので
備忘録がてら書こうと思います

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [任意のTimePickerのテーマだけ編集したい場合](#任意のTimePickerのテーマだけ編集したい場合)
2. [プロジェクト内全てのTimePickerのテーマを編集したい場合](#プロジェクト内全てのTimePickerのテーマを編集したい場合)
3. [最後に](#最後に)
4. [参考文献](#参考文献)

# 任意のTimePickerのテーマだけ編集したい場合
デフォルトのTimePickerは以下のような感じです
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126590/1299477f-7cb8-f7b1-ac53-988ebf473cc0.png" width="200" height=456px>

showTimePicker関数内でテーマを設定できます
```dart
await showTimePicker(context: context, initialTime: initialTime, 
  builder: (context, child){
    return Theme(
        data: Theme.of(context).copyWith(
          timePickerTheme: TimePickerThemeData(
            // ここに任意のプロパティを設定していく
          )
        ),
        child: child!,
    );
  }
);
```

設定できるプロパティは以下です

**Color? backgroundColor**
TimePickerの背景色を設定

**BorderSide? dayPeriodBorderSide**
AM/PM部分の枠組みの太さ、色を設定

**Color? dayPeriodColor**
AM/PM部分の背景色を設定

**OutlinedBorder? dayPeriodShape**
AM/PM部分がデフォルトでは四角形だが他の形に設定

**Color? dayPeriodTextColor**
AM/PM部分のテキストカラーを設定

**TextStyle? dayPeriodTextStyle**
AM/PM部分のテキストスタイルを設定

**Color? dialBackgroundColor**
ダイヤル部分の背景色を設定

**Color? dialHandColor**
ダイヤル部分の針の色を設定

**Color? dialTextColor**
ダイヤル部分の数字のテキストカラーを設定

**Color? entryModeIconColor**
入力モードアイコンボタン(左下のキーボードアイコン)の色を設定

**TextStyle? helpTextStyle**
ヘッダー(例でいう'SELECT TIME'の箇所)のテキストスタイルを設定

**Color? hourMinuteColor**
選択した時刻セグメント(例でいう'10:00'の部分)の背景色を設定

**ShapeBorder? hourMinuteShape**
選択した時刻セグメント部分がデフォルトでは四角形だが他の形に設定

**Color? hourMinuteTextColor**
選択した時刻セグメントのテキストカラーを設定

**TextStyle? hourMinuteTextStyle**
選択した時刻セグメントのテキストスタイルを設定

**InputDecorationTheme? inputDecorationTheme**
入力モード時のテキストボックスの装飾を設定

**ShapeBorder? shape**
TimePicker表示時のダイアログのデフォルトは四角形だが
任意の図形を設定
※指定した図形から中のコンテンツがはみ出した場合もエラーにはならず
表示はされる
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126590/4339f306-657c-40e1-b9ad-f94efd30c9e1.png" width="200" height=456px>



# プロジェクト内全てのTimePickerのテーマを編集したい場合
この場合はアプリ全体のテーマカラーを設定するPrimarySwatchに
任意の色を設定すれば大丈夫です

Flutter側で定義されているMaterialColorを使用するならPrimarySwatchに指定するだけで
簡単に対応できますが、それ以外の色を指定したい場合は自前でMaterialColorを定義する必要があります

弊社のアプリでは`#FC5200`という色をアプリテーマにしているので以下のように対応しました
```dart:main.dart
//~~~~~省略~~~~~

// 自前でMaterialColorを定義する
const MaterialColor customSwatch = MaterialColor(
  0xffFC5200,
  <int, Color>{
    50: Color(0xFFFFEAE0),
    100: Color(0xFFFECBB3),
    200: Color(0xFFFEA980),
    300: Color(0xFFFD864D),
    400: Color(0xFFFC6C26),
    500: Color(0xFFFC5200),
    600: Color(0xFFFC4B00),
    700: Color(0xFFFB4100),
    800: Color(0xFFFB3800),
    900: Color(0xFFFA2800),
  },
);

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // 定義したMaterialColorを指定する
        primarySwatch: customSwatch,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

//~~~~~省略~~~~~
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126590/ec650265-0b52-8336-beca-6e2d8a877f93.png" width="200" height=456px>

よしなにテーマに設定した色がきいた配色にしてくれます

もう少し細かく設定したい場合はMaterialApp内のThemaにTimePickerThemeDataを設定します
```dart:main.dart
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        timePickerTheme: TimePickerThemeData(
          // ここに任意のプロパティを設定していく
        ),
        primarySwatch: customSwatch,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}
```

# 最後に
特に細かいこだわりがなければPrimarySwatchに色を指定するだけが簡単かなと思いました
細かくデザインしたい、TimePickerごとにデザインを変えたい等のこだわりがある場合は
TimePickerThemeDataを利用しての設定という使い分けになるかと思います

# 参考文献
- [TimePickerThemeData class](https://api.flutter.dev/flutter/material/TimePickerThemeData-class.html)
- [showTimePicker function](https://api.flutter.dev/flutter/material/showTimePicker.html)