flutterまとめ personal expense app

#flutter/personal_expense_app

# [Flutter & Dart - The Complete Guide [2020 Edition]](https://www.udemy.com/course/learn-flutter-dart-to-build-ios-android-apps/)

https://www.udemy.com/course/learn-flutter-dart-to-build-ios-android-apps/

*なんのやつか？*
Flutter & Dart - The Complete Guide [2020 Edition]
というUdemyのコースをやっていて便利そうだなと思ったのを備忘録的に載せていく
※コースをやっている途中からノートを取り始めたので、随時追加する
これ便利：https://qiita.com/matsukatsu/items/e289e30231fffb1e4502

#### Source Code
https://github.com/yuks0810/personal_expense_app
コメントとかで補足しているのでこっちを見てもわかるかも。

## Personal Expense App
支出管理とかのアプリ作成
   * 下の画像のように下側からニュッと出てきた部分をグレーアウトしている背景部分をタップすることによってしまうようにする。

### Floatで出てきたwindow（Widget?）をグレーアウトしたバックグラウンドをタップすることでしまうようにする。

[Flutter GestureDetectorの使い方とタッチイベント検出まとめ](https://qiita.com/kurun_pan/items/4d345075064a478a6b28)

`GestureDetector`というWidgetで隠す機能を作れる。
https://api.flutter.dev/flutter/widgets/GestureDetector-class.html

・`behavior: HitTestBehavior.opaque`という引数を取ることで背景や一つ前のWidgetをクリックした時に発火するようになる。

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3338313731302f38306639303032362d303737662d613236342d393166312d6137306138393066393832332e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381710/55ed3799-c4d1-5549-651d-57acf01ba038.png)


```dart
void _startAddNewTransaction(BuildContext ctx) {
    showModalBottomSheet(
        context: ctx,
        builder: (_) {
          // 背景をタッチしたらNewTransactionが閉じるようにしている
          return GestureDetector(
            onTap: () {},
            child: NewTransaction(_addNewTransaction),
            behavior: HitTestBehavior.opaque,
          );
        });
  }
```

# ポップアップフィールドを自動的にしまう

Navigator Widgetを使うことで自動的にフィールドをしまうことができる。
[FlutterのNavigatorの使い方と仕組み](https://qiita.com/heavenosk/items/9e43298955a371221393)

この記事にあるように Navigator popは前の画面に戻る動作をするので、ポップアップしたフィールドを前の画面に戻すことで自動的にしまう操作を実現できる。
※ここでの`context`は親Widget Stateの変数にアクセスできるようにしている。State Widgetの変数をcontextと呼ぶらしい

```dart
Navigator.of(context).pop();
```

## flutter内のThemeを一括で管理する

theme: ThemeDataの`primarySwatch`でテーマカラーを変更することができる。
その結果、フローティングボタンや、Appタイトルの部分を個別に色指定しなくても全体でグローバルに管理することができる。

```dart
class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter App',
      theme: ThemeData(
        primarySwatch: Colors.purple
      ),
      home: MyHomePage(),
    );
  }
}
```

画像ではthemeにpurpleを設定していて、文字列とborderには赤を設定している場合の例

![](2020-08-10-7-31-07.png)


### borderやテキストにもプライマリーでセットした色を適用する

```dart
Container(
      margin: EdgeInsets.symmetric(vertical: 10, horizontal: 15),
      // 値段の周りにボーダーを表示
      decoration: BoxDecoration(
        border: Border.all(
          color: Theme.of(context).primaryColor,
          width: 2,
        ),
      ),
      // 値段の周りにpaddingを追加
      padding: EdgeInsets.all(10),
      // 商品の値段を表示
      child: Text(
        // amountはdoubleなのでtoStringでstring型に直す必要がある。
        '${transactions[index].amount.toStringAsFixed(2)}円', // '\$${tx.amount}',
        // 値段の文字を装飾する
        style: TextStyle(
          fontWeight: FontWeight.bold,
          fontSize: 13,
          color: Theme.of(context).primaryColor,
        ),
      ),
    ),

※contextには様々なメタデータが入っていて、Themeの情報も入っているためTheme変更時に渡してあげる必要がある。
```

これは一部のContainerを抜き出したものだが、`color: Theme.of(context).primaryColor,`としてあげることでprimarySwatchで設定されている色にborderやtextを設定することができる。


```dart
theme: ThemeData(
        primarySwatch: Colors.purple,
        accentColor: Colors.amber,
      ),
```
accentColorも設定可能でフローティングボタンはflutterのデフォルトのものを使っているのでaccentColorが適用されるようになっている。

![](2020-08-10-7-38-47.png)

# 画像の追加

## 画像のローカルの保存場所
- `assets/image/waiting.png`のようにassets配下に任意の名前のフォルダを追加して表示する。
- pubspec.ymlの`assets`部分で読み込み場所を指定する
- 
```dart
# To add assets to your application, add an assets section, like this:
  assets:
    - images/a_dot_burr.jpeg
    - images/a_dot_ham.jpeg

```
- ここを書き換えたらアプリをリスタートしないと読み込まないので、リスタートする

# 文字と画像の間に適度なスペースを設けたい
![スクリーンショット 2020-08-13 18.03.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381710/5474c441-c9d0-5525-535e-88270023c7c3.png)

画像のように文字と画像の間にスペースを設けたい時は[SizedBox class ](https://api.flutter.dev/flutter/widgets/SizedBox-class.html)を使うことで解決できる。

```dart
SizedBox(
  width: 200.0,
  height: 300.0,
  child: const Card(child: Text('Hello World!')),
)
```

このようにすることで、好きに幅や高さを合わせることができる。

```dart
width: double.infinity
```
と記述することで、画面幅いっぱいに広げることができる。

```dart
SizedBox(height: 10,),
```
画像の例では、上記を記述して画像とタイトルの間にスペースを作った


![スクリーンショット 2020-08-13 18.09.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381710/00f10731-bea3-2760-bb3e-acb9553873c3.png)