Flutterチュートリアルを咀嚼する part1 -FlutterはWidgetまみれ-

Flutterって一つのソースを書くだけでiOSもAndroidもアプリ作ってくれるんだって
すごいなー
勉強してみよう

#対象のチュートリアル

https://codelabs.developers.google.com/codelabs/first-flutter-app-pt1#0

#コピペしてできあがったもの
スタートアップ企業の名前をつけてあげるために単語二つの組み合わせをリスト化してくれるアプリ

![スクリーンショット 2020-11-17 16.02.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283826/a192fc3c-b4cb-941a-5006-90fcf9a06acb.png)

#ソースコード

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Startup Name Generator',
      home: RandomWords(),
    );
  }
}

class RandomWords extends StatefulWidget {
  @override
  _RandomWordsState createState() => _RandomWordsState();
}

class _RandomWordsState extends State<RandomWords> {
  final _suggestions = <WordPair>[];
  final _biggerFont = TextStyle(fontSize: 18.0);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Startup Name Generator'),
      ),
      body: _buildSuggestions(),
    );
  }

  Widget _buildSuggestions() {
    return ListView.builder(
        padding: EdgeInsets.all(16.0),
        itemBuilder: /*1*/ (context, i) {
          if (i.isOdd) return Divider(); /*2*/

          final index = i ~/ 2; /*3*/
          if (index >= _suggestions.length) {
            _suggestions.addAll(generateWordPairs().take(10)); /*4*/
          }
          return _buildRow(_suggestions[index]);
        });
  }

  Widget _buildRow(WordPair pair) {
    return ListTile(
      title: Text(
        pair.asPascalCase,
        style: _biggerFont,
      ),
    );
  }
}

```

順々にみていこう

##import

```dart
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
```

###package:flutter/material.dart
これがないと始まらないっぽい
Flutterアプリの主役たち

####クラス

#####Widget
https://api.flutter.dev/flutter/widgets/Widget-class.html
Flutterフレームワークの中心的なクラス
FlutterではほとんどのものがWidget
Widget単位でアプリが構築されていく

#####StatelessWidget
https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html
State（状態）を持たないWidget
不変（immutable)であり静的(static)
親のWidgetから引数を与えてあげることで描画される
反対はStatefulWidget

※参考
https://tech-rise.net/difference-between-stateless-widget-and-stateful-widget


#####StatefulWidget
https://api.flutter.dev/flutter/widgets/StatefulWidget-class.html


チュートリアルの中で
```Implementing a stateful widget requires at least two classes: 1) a StatefulWidget class that creates an instance of 2) a State class. 
```
とあるように、statefulなWidgetを作るためには、②Stateクラスのインスタンスを生成する①StatefulWidgetクラスを用意する必要がある。
要はStateクラスとセットということらしい。

#####State
https://api.flutter.dev/flutter/widgets/State-class.html

StatefulWidgetとセットになるもの。
StatefulWidgetの中でインスタンス化される。
StatefulWidgetのロジックはここで実装する。
Stateクラスの名前の頭には_(アンダーバー)をつける。



#####BuildContext
https://api.flutter.dev/flutter/widgets/BuildContext-class.html


※参考
https://qiita.com/agajo/items/93d75aafe87bdc7b2026
https://itome.team/blog/2019/12/flutter-advent-calendar-day6/

#####MaterialApp
https://api.flutter.dev/flutter/material/MaterialApp-class.html
マテリアルデザインアプリケーションに一般的に必要とされる多くのウィジェットをラップする便利なウィジェット。

#####Scaffold
https://api.flutter.dev/flutter/material/Scaffold-class.html

#####AppBar
https://api.flutter.dev/flutter/material/AppBar-class.html

#####Text
https://api.flutter.dev/flutter/dart-html/Text-class.html

#####ListView
https://api.flutter.dev/flutter/widgets/ListView-class.html

#####EdgeInsets
https://api.flutter.dev/flutter/painting/EdgeInsets-class.html

#####Divider
https://api.flutter.dev/flutter/material/Divider-class.html

####関数
#####runApp()
https://api.flutter.dev/flutter/widgets/runApp.html
指定されたウィジェットを膨らませて、画面に添付する。

####メソッド
#####build()
https://api.flutter.dev/flutter/dart-ui/ParagraphBuilder/build.html
Widgetの主なお仕事の一つ
Widgetをどんな内容で描画するかを決定する

あたりが内包されているライブラリ
これを覚えていくことがはじめの一歩なんでしょう

###package:english_words/english_words.dart
チュートリアルの中で追加したライブラリ
よく使われる英単語を提供してくれる

#####WordPair

#####generateWordPairs

##main()

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

実行部はここだけ
runApp()関数で引数のクラス（MyApp())を膨らませている

main()関数はdartのもの
https://dart.dev/guides/language/language-tour#the-main-function

矢印（=>）構文だけど、これと同じ意味

```dart
void main() {
  runApp(MyApp());
}
```

##MyAppクラス

```dart
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Startup Name Generator',
      home: RandomWords(),
    );
  }
}
```

main()に膨らまされるウィジェット
一番大元なのでStatelessWidgetを拡張したクラスである
build()メソッドを使ってMyAppの内容を描画するMaterialAppをreturnしている
MaterialAppではタイトルとホームの内容を設定している
ホームの中身であるRandomWords()は後述

##RandomWords()


```dart
class RandomWords extends StatefulWidget {
  @override
  _RandomWordsState createState() => _RandomWordsState();
}

class _RandomWordsState extends State<RandomWords> {
  final _suggestions = <WordPair>[];
  final _biggerFont = TextStyle(fontSize: 18.0);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Startup Name Generator'),
      ),
      body: _buildSuggestions(),
    );
  }

  Widget _buildSuggestions() {
    return ListView.builder(
        padding: EdgeInsets.all(16.0),
        itemBuilder: /*1*/ (context, i) {
          if (i.isOdd) return Divider(); /*2*/

          final index = i ~/ 2; /*3*/
          if (index >= _suggestions.length) {
            _suggestions.addAll(generateWordPairs().take(10)); /*4*/
          }
          return _buildRow(_suggestions[index]);
        });
  }

  Widget _buildRow(WordPair pair) {
    return ListTile(
      title: Text(
        pair.asPascalCase,
        style: _biggerFont,
      ),
    );
  }
}


```

大きく分けると
StatefulWidgetのRandomWords
そのStateクラスである_RandomWordsState
がある
チュートリアルが言うにはStatefulWidgetがWidgetそのもので
この中でロジックが記載されているStateクラスをインスタンス化することによってWidgetの内容をstatefulに変更しているとのこと
_RandomWordsStateにはランダムな単語の組み合わせを生成し、リスト形式で表示するためのロジックが記載されている


Flutterではほとんど全てのものがWidgetとあるようにこのクラスにはたくさんのWidgetがある
Scaffold
AppBar
Text
ListView
ListTile

そしてfunctionの戻り値も全てWidgetである
（全部についていて見落としてしまいそうだが頭についてるWidgetは戻り値の型である）
_buildSuggestions()：複数行の単語ペアリストを生成する
_buildRow(WordPair pair)：１行分の単語ペアリストを生成する

スマホのウィジェットを組み合わせてホーム画面をお好みにしていくように
FlutterでもいろんなWidgetを組み合わせてアプリを作っていくようだ

![IMG_0690.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283826/8231510f-9302-c55e-ebbf-7487f73a44df.jpeg)

#Part2
https://qiita.com/Natsukii/items/daca98eac85f73e67ccf