【Flutter】 FlexibleSpaceBarのStretchModesを使ってスライドしたときにびよーんってさせる

#はじめに

Flutter Widget of the Weekで`FlexibleSpaceBar`の`StretchModes`が紹介されたので実際に使ってみました

#作りたいもの

![Stretch_fadetitle.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319622/91e4fe98-7baa-2b5b-167b-4d60ab81e568.gif)


###コード

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        physics: BouncingScrollPhysics(),
        slivers: <Widget>[

          //びよーんの部分
          SliverAppBar(
            stretch: true,
            expandedHeight: 250.0,
            flexibleSpace: FlexibleSpaceBar(
              title: Text('My Dog'),
              background: Image(image: AssetImage("images/mydog.jpg"),
              fit: BoxFit.cover),
              centerTitle: true,

              stretchModes: <StretchMode>[
                StretchMode.zoomBackground,
                StretchMode.blurBackground,
                StretchMode.fadeTitle,
              ],
            ),
          ),

          //ここからスクロールするリストを作る
          SliverFixedExtentList(
            itemExtent: 100.0,
            delegate: SliverChildBuilderDelegate(
                    (BuildContext context, int index) {
                  return Container(
                    alignment: Alignment.center,
                    color: Colors.lightBlue[100 * (index % 2)],
                    child: Text('List Item $index'),
                  );
                },
                childCount: 8
            ),
          ),
        ],
      ),
    );
  }
}
```

#手順

###まずはこれ

![SliverAppBar.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319622/6df68594-78df-7fc0-e86c-e65cb5407d01.gif)



```dart
class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: <Widget>[
          
          //びよーんの部分
          SliverAppBar(
            expandedHeight: 250.0,
            flexibleSpace: FlexibleSpaceBar(
              title: Text('My Dog'),
              background: Image(image: AssetImage("images/mydog.jpg"),
              fit: BoxFit.cover),
              centerTitle: true,
            ),
          ),

          //スクロールするリスト
          SliverFixedExtentList(
            itemExtent: 100.0,
            delegate: SliverChildBuilderDelegate(
                    (BuildContext context, int index) {
                  return Container(
                    alignment: Alignment.center,
                    color: Colors.lightBlue[100 * (index % 2)],
                    child: Text('List Item $index'),
                  );
                },
                childCount: 8
            ),
          ),
        ],
      ),
    );
  }
}
```

・`sliverAppBar`は`CustomScrollView`の子要素として使います。

・`expandedHeight`でスクロールして伸ばしたときに広がる高さを指定します。

・`fit: BoxFit.cover`で画像を幅いっぱいに広げます。



`SliverFixedExtentList`の説明は長くなるので今回は省きます。

ここに説明が載っています。　
[Flutter Doc JP SliverAppBar](https://flutter.ctrnost.com/basic/navigation/sliverappbar/)

##本題

```dart
 body: CustomScrollView(
        physics: BouncingScrollPhysics(),
        slivers: <Widget>[
```

```dart
SliverAppBar(
            stretch: true,
            expandedHeight: 250.0,
```

・`BouncingScrollPhysics`を使います。
これを使い忘れていて、めちゃくちゃ手こずりました。

・`SliverAppBar`の`stretch`を`true`にします。

これで`StretchModes`を使って、スクロールしたときのエフェクトをつけられるようになります。


```dart
flexibleSpace: FlexibleSpaceBar(
              title: Text('My Dog'),
              background: Image(image: AssetImage("images/mydog.jpg"),
              fit: BoxFit.cover),
              centerTitle: true,

              //ここでStretchModesでを使います。
            ),
```
　

`StretchMode.zoomBackground`でスクロールしたときにズームさせます。

```dart
stretchModes: <StretchMode>[
                StretchMode.zoomBackground,
              ],
```
![Stretch_zoom.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319622/3c8ae9ac-24cf-3432-4a1b-9ebe9bd438aa.gif)
 
`strethMode.blurBackground`でスクロールしたときにぼやけさせます。

```dart
stretchModes: <StretchMode>[
                StretchMode.zoomBackground,
                StretchMode.blurBackground,
              ],
```

![Stretch_blur.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319622/2fe16bfc-b5c0-8aa0-a5c1-93a6d6bd7f1c.gif)


`StrethMode.fadeTitle`でスクロールしたときにタイトルを消します。

```dart
stretchModes: <StretchMode>[
                StretchMode.zoomBackground,
                StretchMode.blurBackground,
                StretchMode.fadeTitle,
              ],
```

![Stretch_fadetitle.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319622/1a7ba8ee-c960-70a2-0dd5-e7e8d75b439f.gif)


#まとめ

今回はFlutter Widget of the Weekで紹介された`FlexibleSpaceBar`を使ってみました。
勉強になるので随時取り上げていきたいと思っています。

#参考文献

・[SliverAppBar - Configurable overscroll stretch with callback feature & FlexibleSpaceBar support](https://github.com/flutter/flutter/pull/42250)

・[SliverAppBar class](https://api.flutter.dev/flutter/material/SliverAppBar-class.html)

・[CustomScrollView class](https://api.flutter.dev/flutter/widgets/CustomScrollView-class.html)