Flutterの便利なWidget(FittedBox/adaptive/Wrap)


Flutterには便利なWidgetがたくさんありますよね。
その中でも、最近使って「便利だな〜」と思ったWidgetを3つ紹介します！
今後もどんどん便利なWidgetは取り入れていきたいと思います。

#FittedBox

widgetを入れ子にした場合、子Widgetが親Widgetのサイズに収まりきらないことがあります。
FittedBoxを使えば、幅や高さを細かく指定することなく、子Widgetをピッタリ収めることができます。

・はみ出てしまう子Widget

```
          // FittedBoxを使わない場合、はみ出てしまう。
          Center(
            child: Container(
              width: 300,
              height: 150,
              color: Colors.deepOrange,
              padding: const EdgeInsets.all(10),
              child: const Text(
                'はみ出るぞ!',
                style: TextStyle(
                  fontSize: 80,
                  color: Colors.white,
                  fontWeight: FontWeight.bold,
                ),
              ),
            ),
          ),
```

![FittedBoxを未使用の場合.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317889/ceb5a48b-43b0-ffa5-4c78-2c8ec0053f7c.png)

・FittedBoxを使用するとピッタリ収まる

```
              // FittedBoxを使う場合、fontSizeそのままでもはみ出ない。
              child: const FittedBox(
                child: Text(
                  'はみ出ない!',
                  style: TextStyle(
                    fontSize: 80,
                    color: Colors.white,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ),
```

![FittedBoxを使用の場合.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317889/47e205fa-c3d5-e66c-987c-e32643ca0ee0.png)

・親Widgetの高さを小さくしても、ピッタリ収まる

```
          // FittedBoxを使う場合、fontSizeそのままで高さを縮めてもはみ出ない。
          Center(
            child: Container(
              width: 300,
              height: 80, // 高さを小さくする
              color: Colors.deepOrange,
              padding: const EdgeInsets.all(10),
              child: const FittedBox(
                child: Text(
                  'はみ出ない!',
                  style: TextStyle(
                    fontSize: 80,
                    color: Colors.white,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ),
            ),
          ),
```

![FittedBoxを使用、高さ変更の場合.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317889/72849724-74b0-13cf-f41e-c27465d96dd4.png)

#Adaptive

iOS/Androidの各プラットフォームでは、特有の見慣れたWidgetが存在します。
それぞれ、Cupertino/Material Widgetを使用して表現することも可能ですが、一部のWidgetでは.adaptiveによって、同じソースコードで出し分けることができます。
クロスプラットフォームならではですね！

```
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            // .adaptiveのWidgetはAndroid/iOSのプラットフォーム毎に出し分けてくれる。
            Slider.adaptive(
              value: 1,
              onChanged: (double newValue) {},
            ),
            SwitchListTile.adaptive(
              title: const Text('Switch List Tile Sample'),
              value: true,
              onChanged: (bool newValue) {},
            ),
            Switch.adaptive(
              value: true,
              onChanged: (bool newValue) {},
            ),
            Icon(
              Icons.adaptive.share,
            ),
            const CircularProgressIndicator.adaptive(),
          ],
        ),
```

▼iOS
![adaptive_iOS.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317889/db1ed5ae-4922-da76-598e-5e649ea38173.gif)

▼Android
![adaptive_Android.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317889/7dee95c7-112c-f1ec-3d7b-2c536daf54fc.gif)

#Wrap

画像などの要素を並べて表示することがあると思います。
ただし、画面幅を越えてしまうとエラー(A RenderFlex overflowed by 〜 pixels on the right.)が発生します。
そんな時はWrapを使えば、要素が画面幅を超えても、良い感じに折り返して表示してくれます。

・Wrapを使用していない場合（エラー発生）

```
            // 要素が画面幅に収まらず、エラーが発生してしまう。(A RenderFlex overflowed by 〜 pixels on the right.)
            Row(
              children: _list,
            ),
```

![not_wrap.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317889/a62416ed-25f2-b162-4fcd-ba9a9e225a66.png)

・Wrapを使用した場合（4つ目の画像が折り返されている）

```
            // 要素が画面幅を超える場合、良い感じに折り返して表示してくれる。（4つ目の画像が折り返されている）
            Wrap(
              children: _list,
            ),
```

![wrap.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317889/e8993d39-4bf3-e704-5c39-b246e9fb9013.png)

#まとめ

Flutterは便利なWidgetが多くて面白いですよね！
これからも色々なWidgetを試していきたいと思います。
部分的な紹介となりましたので、ソースコード全体はGitHubよりご覧ください。

▶ソースコード：https://github.com/iizryo/useful_widget_sample

![useful_widget_samplex.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317889/5f3b3ed3-8b0f-b601-16da-6ab1a86bbd51.png)