Flutterの静的ページを勉強してなんとなくまとめてみた

# はじめに
Flutter勉強中です。
ページを作る上での基本となる静的ページを作成したいと思います。
見返したらあんまりまとまってない感じになってしまいましたが、せっかく書いたので残しておきます。

今回は勉強したてというのもあり、Dartファイルだけしか使ってません。

# 環境
Android Studio
Flutter 1.0

# StatelessWidget
Flutterで静的ページを生成する際には`StatelessWidget`を使用します。

公式のサンプルコードでもあるHello Worldは`StatelessWidget`を継承した`MyApp`クラスを使用して画面を生成しています。

`StatelessWidget`は`build`を実装し、そこに`Widget`を返すために実装していきます。
`StatelessWidget`を使うには`import 'package:flutter/material.dart';`が必須となっているため、使用するファイルではimportしてあげましょう。

さらに起動するためには`main`が必要となるのと、Flutterで起動するには`runApp(Widget app)`を呼ぶ必要があるようなので、このアプリが最小限での構成となっているということもわかります。
（下のコードは公式からの引用です）

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Welcome to Flutter'),
        ),
        body: Center(
          child: Text('Hello World.'),
        ),
      ),
    );
  }
}
```

サンプルとは違い`MaterialApp`を使用しないで本当の最小のHello Worldはこのような感じです。
`Text`だけでも表示はされるのですが、`Center`入れないと左上に表示されてわかりづらいので、入れた方が良いです。
あと、`Text`はテキストの方向がどっちを向くべきかを持っていないので、`textDirection`を必ず指定する必要があります。
`MaterialApp`はデフォルトで指定が入っているので指定する必要がなかったりするようです。

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

void main() => runApp(Center(child: Text('Hello world', textDirection: TextDirection.ltr)));
```

## StatelessWidgetのbuildの戻り値がStatefulWidgetなんだけど
`MaterialApp`の継承元が`StatefulWidget`になっていて、`StatelessWidget`の継承先の`build`で`StatefulWidget`返してていいのかがさっぱり分からなかったので、調べてみました。

まず、Flutterは`Widget`というのがあります。
これを組み合わせることで画面を作成していくことになりますが、`Widget`単位で状態を持つか持たないかというのを実装者自身が選択できます。
`runApp`に与える`Widget`は一番親となるべきというだけで、その子供についてはさらに選択させることが可能ということです。

ただし`runapp`の引数に渡せるWidgetが`StatelessWidget`でなければいけないので、`StatelessWidget`を一番親として存在しなければいけないので、子供だけが選択可能というだけのようです。
そして子供がどういうものなのかは特に指定がないため、`MaterialApp`が指定されて問題ないようです。

``` Dart
class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return TestState();
  }
}
```

```
I/flutter (11015): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (11015): The following assertion was thrown while rebuilding dirty elements:
I/flutter (11015): type 'MyApp' is not a subtype of type 'StatelessWidget'
```

# StatelessなWidgetはどのようなものがあるか
そんな訳で大元がStatelessであってもStatefulが中に存在出来るということが分かりました。
なので、完全な静的ページを作成するには全てがStatelessである必要があることになります。
もしくはStatefulであっても書き換えないということもありえるでしょう。
後者はあんまりやらない方が良いとは思っています。

Flutterは多くのWidgetのあり、最初からそれを覚えるのはとても大変なことです。
Flutterの公式サイトにCatalogが存在しているので、やりながら覚えていくのが良いと思います。
https://flutter.io/docs/development/ui/widgets

Stateless一覧とStateful一覧みたいなのがあると自分としてはうれしいので、そのうちまとめてみようかなと思います。
ざっくりとStatelessなのを探しましたが、`Text`とか`Icon`とか`Button`あたりが該当するようです。
あと、`ListView`のようなものもStatelessに分類されるようです。

ただ、tatefulな方が多そうなので、完全にStatelessなWidgetだけである程度しっかりしたデザインをStatelessだけで表現するのは難しいかもしれません。

# おわりに
Flutterの基礎はWidgetにつまっていると思っていてまずは簡単な静的ページをと思ったのですが、Flutterの思想を知らなければいけませんでした。
`RenderObjectWidget`と`InheritedWidget`というクラスもStatelessとStatefulとは別に存在していますし、思ったより勉強コストが高そうなので、引き続きやっていきます。
この勉強コストの高さがスマホアプリを全然やってないからなのかまではわからないのですが、どうなんでしょうか。