[Flutter] DatePickerを実装＆日本語化してみる

#　目次
[1.はじめに](#1-はじめに)
[2.最終的な画面イメージ](#2-最終的な画面イメージ)
[3.最終的なコード](#3-最終的なコード)
[4.具体的な実装手順](#4-具体的な実装手順)
[5.備考](#5-備考)
[6.おわりに](#6-おわりに)
[7.参考サイト](#7-参考サイト)

#1. はじめに
デフォルトで用意されているDatePicker（カレンダー）を実装する。
実装すると英語のままなので日本語化も行う。

#2. 最終的な画面イメージ
![DatePicker1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2416859/6263f761-e6cd-f6b8-1ff6-13177bd5f2fb.png)

#3. 最終的なコード
```dart
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'DatePickerSample',
      home: Scaffold(
        appBar: AppBar(
          title: Text('DatePickerSample'),
        ),
        body: Center(
          child: DatePicker(),
        ),
      ),
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: [
        const Locale("en"),
        const Locale("ja"),
      ],
    );
  }
}

class DatePicker extends StatefulWidget {
  @override
  _DatePickerState createState() => _DatePickerState();
}

class _DatePickerState extends State<DatePicker> {

  // 現在日時
  DateTime _date = new DateTime.now();

  // ボタン押下時のイベント
  void onPressedRaisedButton() async {
    final DateTime picked = await showDatePicker(
      locale: const Locale("ja"),
      context: context,
      initialDate: _date,
      firstDate: new DateTime(2020),
      lastDate: new DateTime.now().add(new Duration(days: 360))
    );

    if (picked != null) {
      // 日時反映
      setState(() => _date = picked);
    }
  }

  Widget build(BuildContext context) {
    return Container(
        padding: const EdgeInsets.all(70.0),
        child: Column(
          children: <Widget>[
            // 日時表示部分
            Center(child:Text("${_date}")),
            // DatePicker表示ボタン。
            new RaisedButton(onPressed: () => 
              // 押下時のイベントを宣言。
              onPressedRaisedButton(),
              child: new Text('日付選択'),
            )
          ],
        )
    );
  }
}
```

#4. 具体的な実装手順
### 1.showDatePickerを用意する
showDatePickerはFlutterのマテリアルデザインとして既に用意されています。とても便利。

```dart
packages/flutter/lib/src/material/date_picker.dart
```

こちら使って4つの引数（context, initialDate, firstDate, lastDate）を指定する。
最初と最後の日を指定できます。

```dart
final DateTime picked = await showDatePicker(
        context: context,
        initialDate: _date,
        firstDate: new DateTime(2020),
        lastDate: new DateTime.now().add(new Duration(days: 360))
    );
```

### 2.ボタンが押下時のイベントとして宣言する
作ったshowDatePickerをイベントとして宣言しておく。

```dart
// ボタン押下時のイベント
  void onPressedRaisedButton() async {
    final DateTime picked = await showDatePicker(
      context: context,
      initialDate: _date,
      firstDate: new DateTime(2018),
      lastDate: new DateTime.now().add(new Duration(days: 360))
    );

    if (picked != null) {
      // 日時反映
      setState(() => _date = picked);
    }
  }
```

### 3.画面表示エリアとボタンを作る
選択した日時と、DatePickerを表示するためのボタンを作る。（レイアウトは各自の好みで）

```dart
Widget build(BuildContext context) {
  return Container(
      padding: const EdgeInsets.all(70.0),
      child: Column(
        children: <Widget>[
          // 日時表示部分
          Center(child:Text("${_date}")),
          // DatePicker表示ボタン。
          new RaisedButton(onPressed: () => 
            // 押下時のイベントを宣言。
            onPressedRaisedButton(),
            child: new Text('日付選択'),
          )
        ],
      )
  );
}
```

### 4.ここまでのコードで起動してみる
問題なく起動すると、以下のようにDatePickerが立ち上がる。
ボタンを押下するとカレンダーが表示される。

![DatePicker2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2416859/557c4bfa-f749-b128-6d13-f1d43baa74b3.png)

![DatePicker3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2416859/0c637b36-b6f6-1cf6-c495-018e68fd3b6a.png)

### 5.flutter_localizationsパッケージのインストール
pubspec.yamlファイルに「flutter_localizations」を追記します。（もし既にある場合は必要ありません。）

```yaml
dependencies:
  flutter:
    sdk: flutter
  // この行を追加
  flutter_localizations:
    sdk: flutter
```

### 6.import文を追加する
パッケージのインポートを追加した後は、実装しているコードに戻り、インポート文を追加する。

```dart
import 'package:flutter_localizations/flutter_localizations.dart';
```

### 7.サポートするロケールを追加する
MaterialAppにロケールを追加する。

```dart
@override
Widget build(BuildContext context) {
  return MaterialApp(
    // 一部省略
    title: 'DatePickerSample',
    home: Scaffold(),
    // ここを追加する。
    localizationsDelegates: [
      GlobalMaterialLocalizations.delegate,
      GlobalWidgetsLocalizations.delegate,
    ],
    // ここを追加する。
    supportedLocales: [
      const Locale("en"),
      const Locale("ja"),
    ],
  );
}
```

### 8.showDatePickerにロケールを追加する
4つの引数からロケールを増やす。

```dart
final DateTime picked = await showDatePicker(
    // ここを追加
    locale: const Locale("ja"),
    context: context,
    initialDate: _date,
    firstDate: new DateTime(2018),
    lastDate: new DateTime.now().add(new Duration(days: 360))
    );
```

### 9.再ビルド
再ビルドすると、画像のように日本語化が出来ています。
![DatePicker1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2416859/fa02dfce-d03c-d63f-aade-25617c434fa8.png)


#5. 備考
パッケージを追加した後、VScodeなどではポップアップでパッケージを取得するボタンが表示されたら最新を取得します。
ポップアップが表示されない場合は、ターミナルで以下コマンドを実行してください。

```dart
flutter pub get
```

#6. おわりに
[Flutter Doc JP](https://flutter.ctrnost.com/basic/interactive/form/datapicker/)
にある、時刻をUIで設定出来るダイアログあるけど使う出番はあるのかな。
より良い実装方法などありましたらご教授いただけると嬉しいです。

#7. 参考サイト
- https://docs.flutter.dev/development/packages-and-plugins/using-packages
- https://api.flutter.dev/flutter/flutter_localizations/GlobalMaterialLocalizations-class.html
- https://flutter.ctrnost.com/basic/interactive/form/datapicker/
- https://webbibouroku.com/Blog/Article/flutter-datepicker-ja!