Flutter 初心者が知りたい小技集 ① ウィジェットの分割


## はじめに

最近 Flutter の勉強をしなおしています。非常に基本的な部分も含まれるかもしれませんが自身の備忘録も兼ねてテクニックを記述しておこうと思います。第一回はコードの見通しを良くするためのウィジェットの分割です。

小技集
> [Flutter 初心者が知りたい小技集 ② ナビゲーションの書き方](https://qiita.com/em0/items/e40ae622b43d7dfd5bc0)
> [Flutter 初心者が知りたい小技集 ③ asyncとawaitを使ったhttp通信](https://qiita.com/em0/items/396851bcd213dff4422e)
> [Flutter 初心者が知りたい小技集 ④ SharedPreferencesでMapを扱う](https://qiita.com/em0/items/e04f3cf87240f5fb7496)

## ウィジェットの分割

Flutter でなんとなくアプリケーションを作っていたときに悩んだことの一つがファイルが複雑化することでした。どのようにコードを分割していけば良いのかわからなかったので方法を記載します。

### プロジェクトを作成

   `$ flutter create sepalate_widget`

### lib/main.dart

   余計なコメントは削除しています。

   ```
   // lib/main.dart
   .
   .
   .
         body: Center(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
             children: <Widget>[
               Text(
                 'You have pushed the button this many times:',
               ),
               // ここから
               Text(
                 '$_counter',
                 style: Theme.of(context).textTheme.headline4,
               ),
               // ここまで
             ],
           ),
         ),
   .
   .
   .
   ```
   今回はサンプルとしてカウントを表示する部分を分割してみます。

### lib/widgets フォルダの作成と counter.dart ファイルの作成

   ```
   $ mkdir lib/widgets
   $ touch lib/widgets/counter.dart
   ```

### コード

   <img width="511" alt="スクリーンショット 2020-07-29 16.14.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279625/93a2cb04-4f9d-876a-9bd4-c92fa368676b.png">


   vscode だと`st`と打ち込むだけでこのように表示され、StatefullWidget と StatelessWidget の雛形が自動で生成されるので便利です。ウィジェットの名前と import 文を記載するだけですぐに作れます。

   ```
   // lib/widgets/counter.dart
   import 'package:flutter/material.dart';

   class Counter extends StatelessWidget {
     @override
     Widget build(BuildContext context) {
       return Container();
     }
   }
   ```

   中身を main.dart ファイルから移植します。

   ```
   // lib/widgets/counter.dart
   import 'package:flutter/material.dart';

    class Counter extends StatelessWidget {
      final int _counter;
      Counter(this._counter);

      @override
      Widget build(BuildContext context) {
        return Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        );
      }
    }
   ```

   変化がわかるように文章を追加してみましょう。

   <img width="384" alt="スクリーンショット 2020-07-29 16.25.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279625/e9eeb608-9521-3d9c-5518-d227e0e04f21.png">


   vscode だと`Text`を右クリック → リファクターで簡単にリファクタリングが可能です。今回は Column でラップします。

   ```
   // lib/widgets/counter.dart
   import 'package:flutter/material.dart';

    class Counter extends StatelessWidget {
      final int _counter;
      Counter(this._counter);

      @override
      Widget build(BuildContext context) {
        return Column(
          children: <Widget>[
            Text("SEPARETED WIDGETS HERE!"),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        );
      }
    }
   ```

   main.dart ファイルで import して表示させましょう

   ```
    // lib/main.dart
    import 'package:flutter/material.dart';

    import './widgets/counter.dart';
    .
    .
    .
    body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Counter(_counter)
          ],
        ),
      ),
    .
    .
    .
   ```

5. 確認

<img width="285" alt="スクリーンショット 2020-07-29 16.27.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279625/42bfe816-0fae-759f-45a7-e61b800d7aee.png">


このように表示されましたか？

## 終わりに

今回はウィジェットの分割方法と vscode の小技を紹介しました。ウィジェットを分割することで見通しも良く、また管理のしやすいコードが書けるようになると思います。vscode の小技も知らなかった時はガリガリ書いたりとか泥臭いことをやっていたので知っていると便利ですね。

今後は個人的にはまった状態管理や Firebase との連携、フォルダの分け方などを書いていく予定です。ここまで読んでくださりありがとうございました。