// Copyright 2016 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'drawer.dart'; import 'item.dart'; const double _kFlexibleSpaceMaxHeight = 256.0; List _itemsWithCategory(String category) { return kAllGalleryItems.where((GalleryItem item) => item.category == category).toList(); } final List _demoItems = _itemsWithCategory('Demos'); final List _componentItems = _itemsWithCategory('Components'); final List _styleItems = _itemsWithCategory('Style'); class _BackgroundLayer { _BackgroundLayer({ int level, double parallax }) : assetName = 'packages/flutter_gallery_assets/appbar/appbar_background_layer$level.png', parallaxTween = new Tween(begin: 0.0, end: parallax); final String assetName; final Tween 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 animation; @override Widget build(BuildContext context) { // TODO(abarth): Wire up to the parallax of the FlexibleSpaceBar in a way // that doesn't pop during hero transition. Animation effectiveAnimation = kAlwaysDismissedAnimation; return new AnimatedBuilder( animation: effectiveAnimation, builder: (BuildContext context, Widget child) { return new Stack( children: _kBackgroundLayers.map((_BackgroundLayer layer) { return new Positioned( top: -layer.parallaxTween.evaluate(effectiveAnimation), left: 0.0, right: 0.0, bottom: 0.0, child: new Image.asset( layer.assetName, fit: ImageFit.cover, height: _kFlexibleSpaceMaxHeight ) ); }).toList() ); } ); } } class GalleryHome extends StatefulWidget { GalleryHome({ Key key, this.useLightTheme, this.onThemeChanged, this.timeDilation, this.onTimeDilationChanged, this.showPerformanceOverlay, this.onShowPerformanceOverlayChanged }) : super(key: key) { assert(onThemeChanged != null); assert(onTimeDilationChanged != null); assert(onShowPerformanceOverlayChanged != null); } final bool useLightTheme; final ValueChanged onThemeChanged; final double timeDilation; final ValueChanged onTimeDilationChanged; final bool showPerformanceOverlay; final ValueChanged onShowPerformanceOverlayChanged; @override GalleryHomeState createState() => new GalleryHomeState(); } class GalleryHomeState extends State { static final Key _homeKey = new ValueKey("Gallery Home"); static final GlobalKey _scrollableKey = new GlobalKey(); final List _listItems = []; @override void initState() { super.initState(); // The first item in the list just exists to occupy the space behind // the flexible app bar. As it's scrolled out of the way, the app bar's // height will shrink. final double statusBarHeight = (MediaQuery.of(context)?.padding ?? EdgeInsets.zero).top; _listItems.add(new SizedBox(height: _kFlexibleSpaceMaxHeight + statusBarHeight)); final ThemeData themeData = Theme.of(context); final TextStyle headerStyle = themeData.textTheme.body2.copyWith(color: themeData.accentColor); String category; for (GalleryItem galleryItem in kAllGalleryItems) { if (category != galleryItem.category) { if (category != null) _listItems.add(new Divider()); _listItems.add( new Container( height: 48.0, padding: const EdgeInsets.only(left: 16.0), align: FractionalOffset.centerLeft, child: new Text(galleryItem.category, style: headerStyle) ) ); category = galleryItem.category; } _listItems.add(galleryItem); } } @override Widget build(BuildContext context) { return new Scaffold( key: _homeKey, scrollableKey: _scrollableKey, drawer: new GalleryDrawer( useLightTheme: config.useLightTheme, onThemeChanged: config.onThemeChanged, timeDilation: config.timeDilation, onTimeDilationChanged: config.onTimeDilationChanged, showPerformanceOverlay: config.showPerformanceOverlay, onShowPerformanceOverlayChanged: config.onShowPerformanceOverlayChanged ), appBar: new AppBar( expandedHeight: _kFlexibleSpaceMaxHeight, flexibleSpace: new FlexibleSpaceBar( title: new Text('Flutter Gallery'), background: new Builder( builder: (BuildContext context) { return new _AppBarBackground( animation: Scaffold.of(context)?.appBarAnimation ); } ) ) ), appBarBehavior: AppBarBehavior.under, body: new Block( scrollableKey: _scrollableKey, children: _listItems ) ); } }