Flutterの公式ドキュメントを読んで理解する 〜Building layouts/Layouts in Flutter〜

# 目的
Flutter自体は何度か使ったことがあるものの、ただ「使える」だけでなく、ちゃんと理解して使えるようになるべく、一度基本に立ち戻り、公式のドキュメントにしっかり目を通すことにした。
記事の内容はほぼ以下のページの和訳（＋意訳）ですが、~~1週間後の自分と~~、自分と同じように英語のドキュメントを敬遠している方のために記録しました。

# 今回読んだ公式ドキュメントのページ
https://flutter.dev/docs/development/ui/layout

Flutter Docの Development -> User Interface -> Building Layouts の中の1節。長い。。。

# Layouts in Flutter
## What's the point?
>* WidgetはUIの構築に使われるクラスである
* WidgetはレイアウトとUI要素の両方に使われる
* 単純たWidgetを組み合わせて、複雑なWidgetを作る

* Flutterのレイアウトの仕組みのコアはWidgetである
* Flutterでは、レイアウトモデルを含むほぼすべてがWidgetである
* 画像、アイコン、テキストなどFlutterアプリで見えるものはすべてWidgetである
* しかし、見えないものもWidgetだったりする。
* 例えば、`Row`や`Column`、見えるWidgetを整列したりするGridなどである


* より複雑なWidgetを作るために、Widgetを組み合わせてレイアウトを作る
* 例えば以下のスクショは、それぞれのしたにラベルを持つ3つのアイコンを示している。
<img src="https://flutter.dev/assets/ui/layout/lakes-icons-9e75d63c8af0fc5ddf026c71b3e85687548ec29f2f1e06f8e78c546969a21127.png" />
* 以下のスクショは、視覚化されたレイアウトを示していて、それぞれにアイコンとラベルを含む3つのColumnのRowを示している。
<img src="https://flutter.dev/assets/ui/layout/lakes-icons-visual-f9e45691d76ba85d4ea2160941f42c8a2ce1a17d41d6e6aac8f3feb89e679f99.png" />
>Note: このチュートリアルで表示されているスクショは、レイアウトが見えるように`debugPaintSizeEnabled`が`true`に設定されている。詳細は[こちら](https://flutter.dev/docs/development/tools/devtools/inspector)を参照せよ。

* Widgetツリーは以下のようになっている。
<img src="https://flutter.dev/assets/ui/layout/sample-flutter-layout-46c76f6ab08f94fa4204469dbcf6548a968052af102ae5a1ae3c78bc24e0d915.png" />
* これらのほとんどについては期待通りに見えるが、`Container`(ピンクの部分)に関しては疑問に思うだろう
* `Container`はその子WidgetをカスタマイズできるようにするWidgetクラスである。
* PaddingやMargin、BorderやBackground Colorを追加したいときは`Container`を使う
* この例では、各`Text`widgetはマージンを追加するために`Container`に配置されている。
* `Row`全体も、Rowの周りにPaddingをつけるために`Container`に配置している。


* この例の残りのUIは、プロパティによって制御されている
* `color`プロパティを使って、`Icon`の色をセットしている
* フォントや色、太さなどをセットするためには、`Text.style`プロパティを使う
* `Column`や`Row`は、以下のようなプロパティを持っている
    * 子Widgetsを垂直か水平のどちらに並べるかを指定する
    * 子Widgetsがどの程度のスペースを占有するか指定する

## Lay out a widget
* このセクションでは、単純なWidgetの作り方と表示のしかたを示す
* あと、シンプルなHello worldアプリのコードも示す

### 1. Select a layout widget
* 見えるWidgetをどう並べたいかに基づいて、[Layout widgets](https://flutter.dev/docs/development/ui/widgets/layout)から選ぶ。
* Layout Widgetsの特性は、たいてい含まれるWidgetにも渡される。
>Layout widgetsには、上述した`Row`とか`Column`、`Padding`の他に、`Center`や、`ListView`、`Table`など様々な種類のWidgetが用意されている。

### 2. Create a visible widget
#### Text widget
```dart
Text("Hello, world"),
```
#### Image widget
```dart
Image.asset(
  'images/lake.jpg',
  fit: BoxFit.cover,
),
```
### Icon widget
```dart
Icon(
  Icons.star,
  color: Colors.red[500],
),
```
### 3. Add the visible widget to the layout widget
* すべてのLayout widgetsは、以下のいずれかを持っている
    * 単一の子を持つ場合(例えば`Center`や`Container`)、`child`プロパティを持つ
    * 子にWidgetのリストを持つ場合(例えば`Row`,`Column`,`ListView`,`Stack`)は、`children`プロパティを持つ
* `Text`widgetを`Center`に入れる場合、こうなる。

```dart
Center(
  child: Text('Hello World'),
),
```
### 4. Add the layout widget to the page
* Flutterアプリは、それ自体がWidgetであり、ほとんどのWidgetは`build()`関数を持っている
* アプリの`build()`関数でWidgetをインスタンス化し返すと、Widgetが表示される
#### Material app
* Materialアプリのためには、`Scaffold`widgetを使うことができる。
* それは、デフォルトのバナーや背景色を提供し、ドロワーやスナックバー、ボトムシートを追加するためのAPIを持っている
* `Center`widgetは`body`プロパティに直接加えることができる

```dart
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter layout demo',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter layout demo'),
        ),
        body: Center(
          child: Text('Hello World'),
        ),
      ),
    );
  }
}
```
>Note: Material libraryはMaterial designに沿ったwidgetsを実装している。UIを設計したいときは、標準のWidgets libraryを使用することができるし、Material libraryを使っても良い。混ぜて使うこともできるし、既存のWidgetをカスタマイズすることもできるし、あるいは、カスタムWidgetのセットを構築することもできる

#### Non-Material apps
```dart
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(color: Colors.white),
      child: Center(
        child: Text(
          'Hello World',
          textDirection: TextDirection.ltr,
          style: TextStyle(
            fontSize: 32,
            color: Colors.black87,
          ),
        ),
      ),
    );
  }
}
```
* デフォルトで、Materialでないアプリは`AppBar`やtitle, background colorを含んでいない
* 非マテリアルアプリにこれらを入れたい場合は、自分で作る必要がある
* 上記のアプリでは、Materialアプリっぽくするために、背景色を白に、テキストをダークグレーに変えている
<img src="https://flutter.dev/assets/ui/layout/hello-world-4ad7a5134f8a38ced291e606a3be4db84b00f68c357af9fefd2732d2cc8bb067.png" />

## Lay out multipe widgets vertically and horizontally
* 最も一般的なレイアウトパターンの一つは、Widgetsを垂直または水平に並べるものである
* 水平の並べたい場合は`Row`、垂直に並べたい場合は`Column`を使うことができる
>What's the point?
>* `Row`と`Column`は最もよく使われるレイアウトパターンの2つ
>* `Row`と`Column`はどちらも子widgetsのリストを受け取る
>* 子widgetは、`Row`や`Column`、またはそれ以外の複雑なWidgetを指定できる
>* 特定の子Widgetを伸ばしたり、制限したりできる
>* 子Widgetsが`Row`や`Column`の利用可能な領域をどの程度使うかを指定できる

* Flutterで行や列を作るには、`Row`または`Column`widgetに子widgetsのリストを加える
* 各子widgetは、行や列などになることができる
* 以下の例は、`Row`や`Column`の中にどうネストできるのかを示している
<img src="https://flutter.dev/assets/ui/layout/pavlova-diagram-8b3d410640d9b3575d69c0724203c5dff6814fdd1a57546a5f65f98254077a92.png" />
* このレイアウトは、`Row`で構成されている。
* `Row`は2つの子を含んでいる。左の`Column`と、右の画像である。
<img src="https://flutter.dev/assets/ui/layout/pavlova-left-column-diagram-c9bf1a39b39270615ce8e82608952ac3edaa0d1eab8691f8783e6408fdfbdfb3.png" />
* 左の列のWidgetツリーは、`Row`と`Column`をネストしている
* コードは[こちら](https://flutter.dev/docs/development/ui/layout#nesting-rows-and-columns)
>Note: `Row`と`Column`は水平・垂直なレイアウトの基本的なプリミティブWidgetであり、これらの低レベルなWidgetで最大限のカスタマイズが可能になる。Flutterは特別な高レベルのWidgetも提供している。例えば、`Row`の代わりに`ListTile`を使うと、leading, trailingアイコンや3行までのテキストを持った使いやすいWidgetがある。`Column`の代わりに、コンテンツが長すぎてスペースに収まらない場合に自動的にスクロールする列のようなレイアウト`ListView`を選択できる。詳細は[こちら](https://flutter.dev/docs/development/ui/layout#common-layout-widgets)

### Aligning widgets
* `mainAxisAlignment`プロパティと`crossAxisAlignment`プロパティを使うことで子Widgetsをどう整列させるかをコントロールできる
* 行では、main axisは水平に、cross axisは垂直に走っている
* 列では、main axisは垂直に、cross axisは水平に走っている

<img src="https://flutter.dev/assets/ui/layout/row-diagram-ad51795e19e3e1d412815b287c9caa694ad357892e3ab8b3ef1da0c4c6e011db.png" />
<img src="https://flutter.dev/assets/ui/layout/column-diagram-4e2ce8e33c32a09d090280fb7b2925baaf58f6de7876a551c207ab904e2fafc6.png" />

* `MainAxisAlignment`クラスと`CrossAxisAlignment`クラスは配置をコントロールするための様々な制約を提供している
>Note: 画像を追加したい場合は、それらにアクセスするために`pubspec.yaml`ファイルを更新する必要がある。より詳しい情報は、この例の[pubspec.yaml](https://github.com/flutter/website/tree/master/examples/layout/row_column/pubspec.yaml)か、[Adding assets and images](https://flutter.dev/docs/development/ui/assets-and-images)を参照してね。`Image.network`でオンラインの画像を参照しているときは必要ない。

* 以下の例では、3つの画像それぞれは100pxの幅である
* レンダーボックス(この場合スクリーン全体)は300pxより広いため、main axisの配置を`spaceEvenly`に設定すると、各画像の間と前後が均等になるように水平の空間が分割された
<img src="https://flutter.dev/assets/ui/layout/row-spaceevenly-visual-bae00ee7fc0b8a0fbe46d74b113f9f0e4e4942e55609cf263cefca81f986d871.png" />

```dart
Row(
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  children: [
    Image.asset('images/pic1.jpg'),
    Image.asset('images/pic2.jpg'),
    Image.asset('images/pic3.jpg'),
  ],
);
```

* `Column`も`Row`と同様に動作する
* 以下の例は、それぞれ高さが100pxの3つの画像の列を示している
*  レンダーボックスの高さは300pxより高いため、main axisの配置を`spaceEvenly`に設定すると、各画像の間隔と上下が均等になるように垂直のスペースが分割される

<img src="https://flutter.dev/assets/ui/layout/column-visual-40850f31d83815ccf693076198ae200ed46bc633e185de8484081cde83e9f1d3.png" />

```dart
Column(
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  children: [
    Image.asset('images/pic1.jpg'),
    Image.asset('images/pic2.jpg'),
    Image.asset('images/pic3.jpg'),
  ],
);
```

### Sizing widgets
* レイアウトが大きすぎてデバイスに収まらないときは、影響を受けている端に沿って黄色と黒の縞模様が表示される

<img src="https://flutter.dev/assets/ui/layout/layout-too-large-f97b9d98cbac9a793c4190a6542ef8f31820a92610afcc387400d1fe30358e18.png" />
* `Expanded`widgetを使うことによって、Widgetを行や列の中に収まるようにサイジングすることができる
* レンダーボックスに対して広すぎる画像の行の上記の例をフィットさせるには、各画像を`Expanded`でラップする必要がある

```dart
Row(
  crossAxisAlignment: CrossAxisAlignment.center,
  children: [
    Expanded(
      child: Image.asset('images/pic1.jpg'),
    ),
    Expanded(
      child: Image.asset('images/pic2.jpg'),
    ),
    Expanded(
      child: Image.asset('images/pic3.jpg'),
    ),
  ],
);
```
<img src="https://flutter.dev/assets/ui/layout/row-expanded-2-visual-7003ec3a27b38a2cc925b97abfd933fe6d2fce62494400e0e3c9790b715cd0d1.png" />
 
* ある1つのWidgetが、その兄弟widgetの2倍のスペースを占めるようにしたい場合を考える
* これに対しては、`Expanded`widgetの`flex`プロパティを使う。
* `flex`プロパティは、Widgetのフレックス係数を決める整数で、デフォルトは1である
* 以下の例は、真ん中の画像のフレックス係数を2にした例である。

```dart
Row(
  crossAxisAlignment: CrossAxisAlignment.center,
  children: [
    Expanded(
      child: Image.asset('images/pic1.jpg'),
    ),
    Expanded(
      flex: 2,
      child: Image.asset('images/pic2.jpg'),
    ),
    Expanded(
      child: Image.asset('images/pic3.jpg'),
    ),
  ],
);
```
<img src="https://flutter.dev/assets/ui/layout/row-expanded-visual-fa9a01df7b96ba5cb33162b91369658fea86554139953e3cc0357de83281133d.png" />

### Packing widgets
* デフォルトでは、行や列はmain axisに沿って可能な限りのスペースを占めるが、子widgetsを密に詰めたい場合は、`mainAxisSize`を`MainAxisSize.min`にセットする。
* 以下の例は、このプロパティを使ってスターアイコンを密に詰めた例である。

```dart
Row(
  mainAxisSize: MainAxisSize.min,
  children: [
    Icon(Icons.star, color: Colors.green[500]),
    Icon(Icons.star, color: Colors.green[500]),
    Icon(Icons.star, color: Colors.green[500]),
    Icon(Icons.star, color: Colors.black),
    Icon(Icons.star, color: Colors.black),
  ],
)
```
<img src="https://flutter.dev/assets/ui/layout/packed-5583166ea8f018a2c3c829cb075eb63b465cf859e74ae1d7792d2c50813e32aa.png" />

### Nesting rows and columns
* レイアウトフレームワークを使うと、行と列の中に行や列を必要なだけ深くネストすることができる
* 以下のレイアウトの囲まれた部分を見よ
<img src="https://flutter.dev/assets/ui/layout/pavlova-large-annotated-05a910e84242ba5185fe735515cb3f794640f49493036631ec99f768dce107c6.png" />
* 囲まれた部分は、2つの行で実装されている。
* レーティングの行は、5つの星とレビューの数を含んでいる。
* アイコンの行は、アイコンとテキストの3つの列を含んでいる。
* レーティングの行のWidgetツリーは、以下の通りである。
<img src="https://flutter.dev/assets/ui/layout/widget-tree-pavlova-rating-row-7555ca5c12948715086787af2783d2e489e44117928b798f4c5d05bb8bec5119.png" />
* `ratings`変数は、5つのスターアイコンとテキストの小さい行を作っている。  

```dart
var stars = Row(
  mainAxisSize: MainAxisSize.min,
  children: [
    Icon(Icons.star, color: Colors.green[500]),
    Icon(Icons.star, color: Colors.green[500]),
    Icon(Icons.star, color: Colors.green[500]),
    Icon(Icons.star, color: Colors.black),
    Icon(Icons.star, color: Colors.black),
  ],
);

final ratings = Container(
  padding: EdgeInsets.all(20),
  child: Row(
    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
    children: [
      stars,
      Text(
        '170 Reviews',
        style: TextStyle(
          color: Colors.black,
          fontWeight: FontWeight.w800,
          fontFamily: 'Roboto',
          letterSpacing: 0.5,
          fontSize: 20,
        ),
      ),
    ],
  ),
);
```
>Tips: 大きくネストされたコードによる視覚的な混乱を最小限にするために、変数や関数にUIの部品を実装する。

* アイコンの行は3つの列を含んでいて、各列はアイコンと2行のテキストを含んでいる
* Widgetツリーは以下
<img src="https://flutter.dev/assets/ui/layout/widget-tree-pavlova-icon-row-f3c4d7f703df25139611c19d59877196fb4292b10ded60066ceeca974402dc2f.png" />
* `iconList`変数はアイコンの行を定義する

```dart
final descTextStyle = TextStyle(
  color: Colors.black,
  fontWeight: FontWeight.w800,
  fontFamily: 'Roboto',
  letterSpacing: 0.5,
  fontSize: 18,
  height: 2,
);

// DefaultTextStyle.merge() allows you to create a default text
// style that is inherited by its child and all subsequent children.
final iconList = DefaultTextStyle.merge(
  style: descTextStyle,
  child: Container(
    padding: EdgeInsets.all(20),
    child: Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: [
        Column(
          children: [
            Icon(Icons.kitchen, color: Colors.green[500]),
            Text('PREP:'),
            Text('25 min'),
          ],
        ),
        Column(
          children: [
            Icon(Icons.timer, color: Colors.green[500]),
            Text('COOK:'),
            Text('1 hr'),
          ],
        ),
        Column(
          children: [
            Icon(Icons.restaurant, color: Colors.green[500]),
            Text('FEEDS:'),
            Text('4-6'),
          ],
        ),
      ],
    ),
  ),
);
```
* `leftColumn`変数はレーティングの行とアイコンの行を含んでいる。

```dart
final leftColumn = Container(
  padding: EdgeInsets.fromLTRB(20, 30, 20, 20),
  child: Column(
    children: [
      titleText,
      subTitle,
      ratings,
      iconList,
    ],
  ),
);
```
* 左の列は、幅を制限するために`Container`に配置される。
* 最後に、`Card`の中の行全体(左の列と画像を含む)としてUIが構築される


* `Image.network()`を使うことでネットから画像を埋め込むことができる
* しかし、この例では`pubspec file`に追加されプロジェクトに直接保存されている
* アクセスには`Images.asset()`を使っている
* より詳しい情報はこちら → [Adding asset and images](https://flutter.dev/docs/development/ui/assets-and-images)

```dart
body: Center(
  child: Container(
    margin: EdgeInsets.fromLTRB(0, 40, 0, 30),
    height: 600,
    child: Card(
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Container(
            width: 440,
            child: leftColumn,
          ),
          mainImage,
        ],
      ),
    ),
  ),
),
```
>Tips: Pavlovaの例はタブレットのような広いデバイスでは最適に水平に実行される。この例をiOSシミュレーターで実行している場合、**Hardware > Device**メニューから様々なデバイスを選択できる。この例では、iPad Proがおすすめである。向きをランドスケープモードに変えるには、**Hardware > Rotate**を使う。**Window > Scale**でシミュレーター の大きさも変えることができる。

ソース：[pavlova](https://github.com/flutter/website/tree/master/examples/layout/pavlova)

## Common layout widgets
* Flutterには、レイアウトWidgetsの豊富なライブラリがある
* 以下で紹介するものはいくつかの最もよく使われるWidgetである
* (紹介する？)目的は、完璧なリストを見せて圧倒するよりも、できるだけ早く実行することである
* 他の利用可能なWidgetsに関しては、[Widget catalog](https://flutter.dev/docs/development/ui/widgets)や、[API reference docs](https://api.flutter.dev/flutter)の検索ボックスを使ってね
* API docsのWidgetのページには、たいていニーズにより合うかもしれない似たようなWidgetについて紹介されている


* 以下のWidgetは2つのカテゴリに分けられる
* [widgets library](https://api.flutter.dev/flutter/widgets/widgets-library.html)の標準的なWidgetと、[Material library](https://api.flutter.dev/flutter/material/material-library.html)の特別なWidgetである
* widget libraryはどのアプリでも使えるが、Material components libraryはMaterialアプリでしか使えない

### Standard widgets
* [Container](https://flutter.dev/docs/development/ui/layout#container): paddingやmarign、borderやbackground color、その他の装飾をwidgetに追加する
* [GridView](https://flutter.dev/docs/development/ui/layout#gridview): Widgetをスクロール可能なグリッドとして配置する
* [ListView](https://flutter.dev/docs/development/ui/layout#listview): Widgetをスクロール可能なリストとして表示する
* [Stack](https://flutter.dev/docs/development/ui/layout#stack): 他のwidgetの上に重ねる

### Material widgets
* [Card](https://flutter.dev/docs/development/ui/layout#card): ドロップシャドウと丸角のボックスに関連する情報を配置する
* [LIstTile](https://flutter.dev/docs/development/ui/layout#listtile): 3行のテキストと任意のleading, trailingを行に並べる

### Container
* 多くのレイアウトでは、`Container`を自由に使い、Paddingを使ってWidgetを分離したり、borderやmarignを追加する
* `Container`に全体のレイアウトを配置することでデバイスの背景や背景色、画像を変えることができる

#### Summary (Container)
* PaddingやMargin, borderを追加する
* 背景色や画像を変更する
* ひとつの子Widgetを持つが、その子は`Row`、`Column`やWidgetツリーでも良い
<img src="https://flutter.dev/assets/ui/layout/margin-padding-border-9616dd0d7af45b95e6fcface25cd933b6b4a0fda51c1ab1bb9287bc8ed92c356.png" />

#### Examples (Container)
* このレイアウトはそれぞれ2つの画像を含む2つの行の列で構成されている
* `Container`は列の背景色をライトグレーにするのに使われている

```dart
Widget _buildImageColumn() => Container(
      decoration: BoxDecoration(
        color: Colors.black26,
      ),
      child: Column(
        children: [
          _buildImageRow(1),
          _buildImageRow(3),
        ],
      ),
    );
```
<img src="https://flutter.dev/assets/ui/layout/container-c31fce287ed0d6c2b0de32af625b2351bd8a08c236a2e60578f940c7b4aceece.png" />
* `Container`は、各画像に丸角やMarginをつけるのにも使われている

```dart
Widget _buildDecoratedImage(int imageIndex) => Expanded(
      child: Container(
        decoration: BoxDecoration(
          border: Border.all(width: 10, color: Colors.black38),
          borderRadius: const BorderRadius.all(const Radius.circular(8)),
        ),
        margin: const EdgeInsets.all(4),
        child: Image.asset('images/pic$imageIndex.jpg'),
      ),
    );

Widget _buildImageRow(int imageIndex) => Row(
      children: [
        _buildDecoratedImage(imageIndex),
        _buildDecoratedImage(imageIndex + 1),
      ],
    );
```
### GridView
* `GridView`はWidgetを2次元のリストとして配置するときに使う
* `GridView`は2つの組み立てられたリストを提供する
* あるいは、独自のグリッドを作成することもできる
* `GridView`がコンテンツがレンダーボックスに対して長いことを検知すると、自動的にスクロールする

#### Summary (GridView)
* Widgetをグリッド状に並べる
* 列のコンテンツがレンダーボックスを超えることを検知すると、自動的にスクロールする
* 独自のグリッドを作ることもできるし、用意されたグリッドを使うこともできる
    * `GridView.count`には列の数を指定できる
    * `GridView.extent`にはタイルの最大ピクセルを指定できる
>Note: セルが占める行と列が重要な2次元のリストを表示する際は（例えば、「アボカド」行に対する「カロリー」列のエントリなど）、`Table`や`DataTable`を使う

#### Example (GridView)
<img src="https://flutter.dev/assets/ui/layout/gridview-extent-b36976ff50ecc7d55518fa41c10ac3d6de2c0e8a19d550e607461b46e8722395.png" />
* `GridView.extent`を使って、グリッドタイルを最大150ピクせルにしている

<img src="https://flutter.dev/assets/ui/layout/gridview-count-flutter-gallery-59cdc10fb37f423463da914fe4c298b00f46d8d70f584080898939b9568df44b.png" />
* `GridView.count`を使って、ポートレートモードでは2つのタイルの幅、ランドスケープモードでは3つのタイルの幅にしている
* タイトルは、各`GridTile`に`footer`プロパティを設定して作られている  
Dart code: [grid_list_demo.dart](https://github.com/flutter/flutter/tree/master/dev/integration_tests/flutter_gallery/lib/demo/material/grid_list_demo.dart) @ [Flutter Gallery](https://github.com/flutter/flutter/tree/master/dev/integration_tests/flutter_gallery)

```dart
Widget _buildGrid() => GridView.extent(
    maxCrossAxisExtent: 150,
    padding: const EdgeInsets.all(4),
    mainAxisSpacing: 4,
    crossAxisSpacing: 4,
    children: _buildGridTileList(30));

// The images are saved with names pic0.jpg, pic1.jpg...pic29.jpg.
// The List.generate() constructor allows an easy way to create
// a list when objects have a predictable naming pattern.
List<Container> _buildGridTileList(int count) => List.generate(
    count, (i) => Container(child: Image.asset('images/pic$i.jpg')));
```

### ListView
* `ListView`は、列っぽいWidgetで、コンテンツがレンダーボックスに対して大きい場合自動的なスクロールを提供する

#### Summary (ListView)
* boxのリストを並べる特別な`Column`
* 水平または垂直に配置できる
* コンテンツが大きい場合は、自動的にスクロールする
* `Column`より設定できるものは少ないが、簡単に使え、スクロールもサポートしている

#### Examples (ListView)
```dart
Widget _buildList() => ListView(
      children: [
        _tile('CineArts at the Empire', '85 W Portal Ave', Icons.theaters),
        _tile('The Castro Theater', '429 Castro St', Icons.theaters),
        _tile('Alamo Drafthouse Cinema', '2550 Mission St', Icons.theaters),
        _tile('Roxie Theater', '3117 16th St', Icons.theaters),
        _tile('United Artists Stonestown Twin', '501 Buckingham Way',
            Icons.theaters),
        _tile('AMC Metreon 16', '135 4th St #3000', Icons.theaters),
        Divider(),
        _tile('Kescaped_code#39;s Kitchen', '757 Monterey Blvd', Icons.restaurant),
        _tile('Emmyescaped_code#39;s Restaurant', '1923 Ocean Ave', Icons.restaurant),
        _tile(
            'Chaiya Thai Restaurant', '272 Claremont Blvd', Icons.restaurant),
        _tile('La Ciccia', '291 30th St', Icons.restaurant),
      ],
    );

ListTile _tile(String title, String subtitle, IconData icon) => ListTile(
      title: Text(title,
          style: TextStyle(
            fontWeight: FontWeight.w500,
            fontSize: 20,
          )),
      subtitle: Text(subtitle),
      leading: Icon(
        icon,
        color: Colors.blue[500],
      ),
    );
```
* `ListView`を使って、`ListTile`を使ったビジネスのリストを表示している
* `Divider`はレストランとシアターを分離している

ソース: [grid_and_list](https://github.com/flutter/website/tree/master/examples/layout/grid_and_list) 
<img src="https://flutter.dev/assets/ui/layout/listview-34918a738b5d18af88d16a8773e563a3b97f2ffd2710304c5543f8541cbd1345.png" />

<img src="https://flutter.dev/assets/ui/layout/listview-flutter-gallery-bac5e59b369906556451d427ef42502b1710fcf34a38d4fb0dc409c14a423548.png" />
* `ListView`を使って、Material Design paletteから`Colors`を表示している

ソース: [colors_demo.dart](https://github.com/flutter/flutter/tree/master/dev/integration_tests/flutter_gallery/lib/demo/colors_demo.dart)

### Stack
* `Stack`を使うと、例えば画像とかの基本的なWidgetの上にWidgetを配置できる
* Widgetは完全にあるいは部分的にベースとなるWidgetに重なる

#### Summary (Stack)
* 他のWidgetにWidgetを重ねるのに使う
* childrenリストの最初のWidgetがベースとなるWidgetであり、後のWidgetはそのベースとなるWidgetの上に重ねられる
* `Stack`のコンテンツはスクロールできない
* レンダーボックスをはみ出る子を切り取ることもできる

#### Examples (Stack)
<img src="https://flutter.dev/assets/ui/layout/stack-8b743fe7d0f5fe7e58e3a257572f4b48b1552194f7e3f3ffa15a87edaf99a749.png" />
* `Stack`を使って、`CircleAvatar`の上に`Container`(半透明の黒背景に`Text`を表示している)を重ねている
* `Stack`は、`alignment`プロパティと`Alignment`を使ってtextをオフセットしている

ソース: [card_and_stack](https://github.com/flutter/website/tree/master/examples/layout/card_and_stack)

<img src="https://flutter.dev/assets/ui/layout/stack-flutter-gallery-a90ac4d0242afcd79a8c1e155a6f930ce53960fad61e389108bc73f3f2149e40.png" />
* `Stack`を使って画像の上部にグラデーションを重ねている
* これにより、ツールバーのアイコンがわかりやすくなる

ソース: [contacts_demo.dart](https://github.com/flutter/flutter/tree/master/dev/integration_tests/flutter_gallery/lib/demo/contacts_demo.dart)

```dart
Widget _buildStack() => Stack(
    alignment: const Alignment(0.6, 0.6),
    children: [
      CircleAvatar(
        backgroundImage: AssetImage('images/pic.jpg'),
        radius: 100,
      ),
      Container(
        decoration: BoxDecoration(
          color: Colors.black45,
        ),
        child: Text(
          'Mia B',
          style: TextStyle(
            fontSize: 20,
            fontWeight: FontWeight.bold,
            color: Colors.white,
          ),
        ),
      ),
    ],
  );
```
### Card
* Material libraryの`Card`widgetは、関連した情報の塊を含んでいて、ほぼどのWidgetでも構成できる
* たいていは、`ListTile`と一緒に使われる
* `Card`は単一の子widgetを持つが、その子widgetは`Column`,`Row`,`Grid`、あるいは複数の子widgetを持つことができる他のWidgetでも良い。
* デフォルトでは、`Card`のサイズは0x0ピクセルに縮められる
* カードのサイズを制限するには、`SizedBox`を使うことができる


* Flutterでは、`Card`は少し丸い角やドロップシャドーを持ち、3Dエフェクトを与える
* `Card`の`elevation`プロパティを変更することで、ドロップシャドー効果をコントロールできる
* 例えば、`elevation`を24に設定すると、`Card`を視覚的に表面から浮き上がらせ、影をより分散させる
* サポートされている`elevation`の値については、[Material guidelines](https://material.io/design)の[Elevation](https://material.io/design/environment/elevation.html)を参照

#### Summary (Card)
* Material Cardを実現する
* 関連した情報の塊を表示するのに使う
* 単一の子Widgetを持ち、それは`Row`や`Column`、子Widgetのリストを保持する他のWidgetでも良い
* 丸い角とドロップシャドウで表示
* `Card`のコンテンツはスクロールできない
* Material libraryのWidget

#### Example (Card)
<img src="https://flutter.dev/assets/ui/layout/card-3db18421d33c96f34f8d19889a5f28c61287063a62c9770f311fd56aeff0b364.png" />
* `Card`は3つの`ListTile`を含み、`SizedBox`でそれをラップするように大きさが変わっている
* `Divider`は、1番目と2番目の`ListTile`を分離している

ソース: [card_and_stack](https://github.com/flutter/website/tree/master/examples/layout/card_and_stack)

<img src="https://flutter.dev/assets/ui/layout/card-flutter-gallery-184963eb23d8824ef3df612a6b40205ed113e7c00da98fa22228cc6e6f619d88.png" />
* `Card`は画像やテキストを含んでいる

ソース: [cards_demo.dart](https://github.com/flutter/flutter/tree/master/dev/integration_tests/flutter_gallery/lib/demo/material/cards_demo.dart)

```dart
Widget _buildCard() => SizedBox(
    height: 210,
    child: Card(
      child: Column(
        children: [
          ListTile(
            title: Text('1625 Main Street',
                style: TextStyle(fontWeight: FontWeight.w500)),
            subtitle: Text('My City, CA 99984'),
            leading: Icon(
              Icons.restaurant_menu,
              color: Colors.blue[500],
            ),
          ),
          Divider(),
          ListTile(
            title: Text('(408) 555-1212',
                style: TextStyle(fontWeight: FontWeight.w500)),
            leading: Icon(
              Icons.contact_phone,
              color: Colors.blue[500],
            ),
          ),
          ListTile(
            title: Text('costa@example.com'),
            leading: Icon(
              Icons.contact_mail,
              color: Colors.blue[500],
            ),
          ),
        ],
      ),
    ),
  );
```
### ListTile
* Material libraryの特別な行widgetである`ListTile`を使うと、3行のテキストと任意のleading, trainlingアイコンを含む行を簡単に作ることができる
* `ListTile`は、`Card`や`ListView`でよく使われるが、他の場所でも使える

#### Summary (ListTile)
* 3行のテキストと任意のアイコンを含む、特別な`Row`である
* `Row`より設定可能なものは少ないが、より簡単に使える
* Material libraryのWidget

#### Examples (ListTile)
<img src="https://flutter.dev/assets/ui/layout/card-3db18421d33c96f34f8d19889a5f28c61287063a62c9770f311fd56aeff0b364.png" />
* `Card`は3つの`ListTile`を含んでいる

ソース: [card_and_stack](https://github.com/flutter/website/tree/master/examples/layout/card_and_stack)

<img src="https://flutter.dev/assets/ui/layout/listtile-flutter-gallery-5d28c96af0ea49816b8ea14bbdb65e3116bc342978627f491ed3697895ab34a5.png" />
* `ListTile`を使って、3つのドロップダウンタイプを並べている

Code: [buttons_demo.dart](https://github.com/flutter/flutter/tree/master/dev/integration_tests/flutter_gallery/lib/demo/material/buttons_demo.dart)

## Constraints
* Flutterのレイアウトシステムを完全に理解するには、Flutterがどのようにしてレイアウトの中で配置やサイジングを行っているかを学習する必要がある
* より詳しい情報は、[Understanding constraints](https://flutter.dev/docs/development/ui/layout/constraints)を見てね