LoginSignup
13
9

More than 5 years have passed since last update.

FlutterサンプルアプリGalleryの縮小するヘッダを試す

Last updated at Posted at 2017-04-01

FlutterサンプルアプリにGalleryがあるが、このアプリの縮小(拡大)するヘッダがカッコよかったので、どうやってるのか調べてみた。

どうやらCustomScrollViewに、SliberAppBarとSliberListを指定して実装するらしい。SliberAppBarのbackgroundにはAnimatedBuilderを使用したWidgetも指定しアニメーションさせている様子。

チュートリアルのBuilding Layouts in Flutterにあるlakesのレイアウトに移植して試してみる。

まず、バックグランド関連ソースをコピペし、背景画像のasset名を変更する。

lib/main.dart
const double _kFlexibleSpaceMaxHeight = 256.0;

class _BackgroundLayer {
  _BackgroundLayer({int level, double parallax})
      : assetName = 'images/lake.jpg',
        parallaxTween = new Tween<double>(begin: 0.0, end: parallax);
  final String assetName;
  final Tween<double> parallaxTween;
}

final List<_BackgroundLayer> _kBackgroundLayers = <_BackgroundLayer>[
  new _BackgroundLayer(level: 0, parallax: _kFlexibleSpaceMaxHeight),
  new _BackgroundLayer(level: 1, parallax: _kFlexibleSpaceMaxHeight),
  new _BackgroundLayer(level: 2, parallax: _kFlexibleSpaceMaxHeight / 2.0),
  new _BackgroundLayer(level: 3, parallax: _kFlexibleSpaceMaxHeight / 4.0),
  new _BackgroundLayer(level: 4, parallax: _kFlexibleSpaceMaxHeight / 2.0),
  new _BackgroundLayer(level: 5, parallax: _kFlexibleSpaceMaxHeight)
];

class _AppBarBackground extends StatelessWidget {
  _AppBarBackground({Key key, this.animation}) : super(key: key);

  final Animation<double> animation;

  @override
  Widget build(BuildContext context) {
    return new AnimatedBuilder(
        animation: animation,
        builder: (BuildContext context, Widget child) {
          return new Stack(
              children: _kBackgroundLayers.map((_BackgroundLayer layer) {
            return new Positioned(
                top: -layer.parallaxTween.evaluate(animation),
                left: 0.0,
                right: 0.0,
                bottom: 0.0,
                child: new Image.asset(layer.assetName,
                    fit: BoxFit.cover, height: _kFlexibleSpaceMaxHeight));
          }).toList());
        });
  }
}

次に、Scaffoldに渡していたappBarを削除し、bodyをCustomScrollViewに差し替える。画像はバックグランドの背景で指定したので、SliverListに渡す配列から取り除いておく。

lib/main.dart
    return new MaterialApp(
        title: 'Flutter Demo',
        theme: new ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: new Scaffold(
            body: new CustomScrollView(slivers: <Widget>[
          new SliverAppBar(
            pinned: true,
            expandedHeight: _kFlexibleSpaceMaxHeight,
            flexibleSpace: new FlexibleSpaceBar(
              title: new Text('Top Lakes'),
              // TODO(abarth): Wire up to the parallax in a way that doesn't pop during hero transition.
              background:
                  new _AppBarBackground(animation: kAlwaysDismissedAnimation),
            ),
          ),
          new SliverList(
              delegate: new SliverChildListDelegate(<Widget>[
            titleSection,
            buttonSection,
            textSection,
          ])),
        ])));

あと、直接関係ないけど、ヘッダが縮小しきるにはコンテンツが足りないので、テキストの文字列を適当に追加した。

で、できあがり。ソースはここ

Lakes

13
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
9