mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
236 lines
7.7 KiB
Dart
236 lines
7.7 KiB
Dart
// 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/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'drawer.dart';
|
|
import 'item.dart';
|
|
import 'theme.dart';
|
|
|
|
const double _kFlexibleSpaceMaxHeight = 256.0;
|
|
const String _kGalleryAssetsPackage = 'flutter_gallery_assets';
|
|
|
|
class _BackgroundLayer {
|
|
_BackgroundLayer({ int level, double parallax })
|
|
: assetName = 'appbar/appbar_background_layer$level.png',
|
|
assetPackage = _kGalleryAssetsPackage,
|
|
parallaxTween = new Tween<double>(begin: 0.0, end: parallax);
|
|
final String assetName;
|
|
final String assetPackage;
|
|
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 {
|
|
const _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,
|
|
package: layer.assetPackage,
|
|
fit: BoxFit.cover,
|
|
height: _kFlexibleSpaceMaxHeight
|
|
)
|
|
);
|
|
}).toList()
|
|
);
|
|
}
|
|
);
|
|
}
|
|
}
|
|
|
|
class GalleryHome extends StatefulWidget {
|
|
const GalleryHome({
|
|
Key key,
|
|
this.galleryTheme,
|
|
@required this.onThemeChanged,
|
|
this.timeDilation,
|
|
@required this.onTimeDilationChanged,
|
|
this.textScaleFactor,
|
|
this.onTextScaleFactorChanged,
|
|
this.showPerformanceOverlay,
|
|
this.onShowPerformanceOverlayChanged,
|
|
this.checkerboardRasterCacheImages,
|
|
this.onCheckerboardRasterCacheImagesChanged,
|
|
this.checkerboardOffscreenLayers,
|
|
this.onCheckerboardOffscreenLayersChanged,
|
|
this.onPlatformChanged,
|
|
this.overrideDirection: TextDirection.ltr,
|
|
this.onOverrideDirectionChanged,
|
|
this.onSendFeedback,
|
|
}) : assert(onThemeChanged != null),
|
|
assert(onTimeDilationChanged != null),
|
|
super(key: key);
|
|
|
|
final GalleryTheme galleryTheme;
|
|
final ValueChanged<GalleryTheme> onThemeChanged;
|
|
|
|
final double timeDilation;
|
|
final ValueChanged<double> onTimeDilationChanged;
|
|
|
|
final double textScaleFactor;
|
|
final ValueChanged<double> onTextScaleFactorChanged;
|
|
|
|
final bool showPerformanceOverlay;
|
|
final ValueChanged<bool> onShowPerformanceOverlayChanged;
|
|
|
|
final bool checkerboardRasterCacheImages;
|
|
final ValueChanged<bool> onCheckerboardRasterCacheImagesChanged;
|
|
|
|
final bool checkerboardOffscreenLayers;
|
|
final ValueChanged<bool> onCheckerboardOffscreenLayersChanged;
|
|
|
|
final ValueChanged<TargetPlatform> onPlatformChanged;
|
|
|
|
final TextDirection overrideDirection;
|
|
final ValueChanged<TextDirection> onOverrideDirectionChanged;
|
|
|
|
final VoidCallback onSendFeedback;
|
|
|
|
@override
|
|
GalleryHomeState createState() => new GalleryHomeState();
|
|
}
|
|
|
|
class GalleryHomeState extends State<GalleryHome> with SingleTickerProviderStateMixin {
|
|
static final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
|
|
|
AnimationController _controller;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_controller = new AnimationController(
|
|
duration: const Duration(milliseconds: 600),
|
|
debugLabel: 'preview banner',
|
|
vsync: this,
|
|
)..forward();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_controller.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
List<Widget> _galleryListItems() {
|
|
final List<Widget> listItems = <Widget>[];
|
|
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(const Divider());
|
|
listItems.add(
|
|
new MergeSemantics(
|
|
child: new Container(
|
|
height: 48.0,
|
|
padding: const EdgeInsetsDirectional.only(start: 16.0),
|
|
alignment: AlignmentDirectional.centerStart,
|
|
child: new SafeArea(
|
|
top: false,
|
|
bottom: false,
|
|
child: new Semantics(
|
|
header: true,
|
|
child: new Text(galleryItem.category, style: headerStyle),
|
|
),
|
|
),
|
|
),
|
|
)
|
|
);
|
|
category = galleryItem.category;
|
|
}
|
|
listItems.add(galleryItem);
|
|
}
|
|
return listItems;
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
Widget home = new Scaffold(
|
|
key: _scaffoldKey,
|
|
drawer: new GalleryDrawer(
|
|
galleryTheme: widget.galleryTheme,
|
|
onThemeChanged: widget.onThemeChanged,
|
|
timeDilation: widget.timeDilation,
|
|
onTimeDilationChanged: widget.onTimeDilationChanged,
|
|
textScaleFactor: widget.textScaleFactor,
|
|
onTextScaleFactorChanged: widget.onTextScaleFactorChanged,
|
|
showPerformanceOverlay: widget.showPerformanceOverlay,
|
|
onShowPerformanceOverlayChanged: widget.onShowPerformanceOverlayChanged,
|
|
checkerboardRasterCacheImages: widget.checkerboardRasterCacheImages,
|
|
onCheckerboardRasterCacheImagesChanged: widget.onCheckerboardRasterCacheImagesChanged,
|
|
checkerboardOffscreenLayers: widget.checkerboardOffscreenLayers,
|
|
onCheckerboardOffscreenLayersChanged: widget.onCheckerboardOffscreenLayersChanged,
|
|
onPlatformChanged: widget.onPlatformChanged,
|
|
overrideDirection: widget.overrideDirection,
|
|
onOverrideDirectionChanged: widget.onOverrideDirectionChanged,
|
|
onSendFeedback: widget.onSendFeedback,
|
|
),
|
|
body: new CustomScrollView(
|
|
slivers: <Widget>[
|
|
const SliverAppBar(
|
|
pinned: true,
|
|
expandedHeight: _kFlexibleSpaceMaxHeight,
|
|
flexibleSpace: const FlexibleSpaceBar(
|
|
title: const Text('Flutter Gallery'),
|
|
// TODO(abarth): Wire up to the parallax in a way that doesn't pop during hero transition.
|
|
background: const _AppBarBackground(animation: kAlwaysDismissedAnimation),
|
|
),
|
|
),
|
|
new SliverList(delegate: new SliverChildListDelegate(_galleryListItems())),
|
|
],
|
|
)
|
|
);
|
|
|
|
// In checked mode our MaterialApp will show the default "debug" banner.
|
|
// Otherwise show the "preview" banner.
|
|
bool showPreviewBanner = true;
|
|
assert(() {
|
|
showPreviewBanner = false;
|
|
return true;
|
|
}());
|
|
|
|
if (showPreviewBanner) {
|
|
home = new Stack(
|
|
fit: StackFit.expand,
|
|
children: <Widget>[
|
|
home,
|
|
new FadeTransition(
|
|
opacity: new CurvedAnimation(parent: _controller, curve: Curves.easeInOut),
|
|
child: const Banner(
|
|
message: 'PREVIEW',
|
|
location: BannerLocation.topEnd,
|
|
)
|
|
),
|
|
]
|
|
);
|
|
}
|
|
|
|
return home;
|
|
}
|
|
}
|