First pass at new Flutter gallery front page
This commit is contained in:
parent
9e6e522bb3
commit
d563f50822
@ -23,3 +23,4 @@ assets:
|
|||||||
- packages/flutter_gallery_assets/top_10_australian_beaches.png
|
- packages/flutter_gallery_assets/top_10_australian_beaches.png
|
||||||
- packages/flutter_gallery_assets/jumpingjack.json
|
- packages/flutter_gallery_assets/jumpingjack.json
|
||||||
- packages/flutter_gallery_assets/jumpingjack.png
|
- packages/flutter_gallery_assets/jumpingjack.png
|
||||||
|
- packages/flutter_gallery_assets/grain.png
|
||||||
|
@ -28,10 +28,20 @@ class GalleryAppState extends State<GalleryApp> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return new MaterialApp(
|
return new MaterialApp(
|
||||||
title: 'Flutter Material Gallery',
|
title: 'Flutter Material Gallery',
|
||||||
theme: lightTheme ? new ThemeData.light() : new ThemeData.dark(),
|
theme: lightTheme ? _kGalleryLightTheme : _kGalleryDarkTheme,
|
||||||
routes: {
|
routes: {
|
||||||
'/': (BuildContext context) => new GalleryHome()
|
'/': (BuildContext context) => new GalleryHome()
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ThemeData _kGalleryLightTheme = new ThemeData(
|
||||||
|
brightness: ThemeBrightness.light,
|
||||||
|
primarySwatch: Colors.purple
|
||||||
|
);
|
||||||
|
|
||||||
|
ThemeData _kGalleryDarkTheme = new ThemeData(
|
||||||
|
brightness: ThemeBrightness.dark,
|
||||||
|
primarySwatch: Colors.purple
|
||||||
|
);
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
// 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/widgets.dart';
|
|
||||||
|
|
||||||
typedef Widget GalleryDemoBuilder();
|
|
||||||
|
|
||||||
class GalleryDemo {
|
|
||||||
GalleryDemo({ this.title, this.builder }) {
|
|
||||||
assert(title != null);
|
|
||||||
assert(builder != null);
|
|
||||||
}
|
|
||||||
|
|
||||||
final String title;
|
|
||||||
final GalleryDemoBuilder builder;
|
|
||||||
}
|
|
189
examples/material_gallery/lib/gallery/header.dart
Normal file
189
examples/material_gallery/lib/gallery/header.dart
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_sprites/flutter_sprites.dart';
|
||||||
|
|
||||||
|
class GalleryHeader extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
_GalleryHeaderState createState() => new _GalleryHeaderState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _GalleryHeaderState extends State<GalleryHeader> {
|
||||||
|
_FlutterHeaderNode _headerNode;
|
||||||
|
ImageMap _images;
|
||||||
|
|
||||||
|
Future<Null> _loadAssets() async {
|
||||||
|
final AssetBundle bundle = DefaultAssetBundle.of(context);
|
||||||
|
_images = new ImageMap(bundle);
|
||||||
|
await _images.load(<String>[
|
||||||
|
'packages/flutter_gallery_assets/grain.png',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_loadAssets().then((_) {
|
||||||
|
setState(() {
|
||||||
|
_headerNode = new _FlutterHeaderNode(_images);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return _headerNode == null ? new Container() : new SpriteWidget(_headerNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Size _kCanvasSize = const Size(1024.0, 1024.0);
|
||||||
|
const Point _kCenterPoint = const Point(512.0, 512.0);
|
||||||
|
|
||||||
|
class _FlutterHeaderNode extends NodeWithSize {
|
||||||
|
_FlutterHeaderNode(this._images) : super(_kCanvasSize) {
|
||||||
|
clippingLayer.opacity = 0.0;
|
||||||
|
clippingLayer.actions.run(new ActionTween((double a) => clippingLayer.opacity = a, 0.0, 1.0, 0.5));
|
||||||
|
addChild(clippingLayer);
|
||||||
|
|
||||||
|
clippingLayer.addChild(new _BackgroundBox());
|
||||||
|
|
||||||
|
paperAnimation.position = _kCenterPoint;
|
||||||
|
clippingLayer.addChild(paperAnimation);
|
||||||
|
|
||||||
|
final Sprite grain = new Sprite.fromImage(_images['packages/flutter_gallery_assets/grain.png'])
|
||||||
|
..position = _kCenterPoint;
|
||||||
|
clippingLayer.addChild(grain);
|
||||||
|
|
||||||
|
userInteractionEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ImageMap _images;
|
||||||
|
final Layer clippingLayer = new Layer();
|
||||||
|
final _PaperAnimation paperAnimation = new _PaperAnimation();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void spriteBoxPerformedLayout() {
|
||||||
|
clippingLayer.layerRect = spriteBox.visibleArea;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<_PaperConfig> _kPaperConfigs = <_PaperConfig>[
|
||||||
|
new _PaperConfig(
|
||||||
|
color: Colors.deepPurple[500],
|
||||||
|
startPosition: const Point(-300.0, -300.0),
|
||||||
|
startRotation: -10.0,
|
||||||
|
rotationSpeed: -1.0,
|
||||||
|
parallaxDepth: 0.0,
|
||||||
|
rect: new Rect.fromLTRB(-1024.0, -280.0, 1024.0, 280.0)
|
||||||
|
),
|
||||||
|
new _PaperConfig(
|
||||||
|
color: Colors.purple[400],
|
||||||
|
startPosition: const Point(550.0, 0.0),
|
||||||
|
startRotation: 45.0,
|
||||||
|
rotationSpeed: 0.7,
|
||||||
|
parallaxDepth: 1.0,
|
||||||
|
rect: new Rect.fromLTRB(-512.0, -512.0, 512.0, 512.0)
|
||||||
|
),
|
||||||
|
new _PaperConfig(
|
||||||
|
color: Colors.purple[600],
|
||||||
|
startPosition: const Point(550.0, 0.0),
|
||||||
|
startRotation: 55.0,
|
||||||
|
rotationSpeed: 0.9,
|
||||||
|
parallaxDepth: 2.0,
|
||||||
|
rect: new Rect.fromLTRB(-512.0, -512.0, 512.0, 512.0)
|
||||||
|
),
|
||||||
|
new _PaperConfig(
|
||||||
|
color: Colors.purple[700],
|
||||||
|
startPosition: const Point(550.0, 0.0),
|
||||||
|
startRotation: 65.0,
|
||||||
|
rotationSpeed: 1.1,
|
||||||
|
parallaxDepth: 3.0,
|
||||||
|
rect: new Rect.fromLTRB(-512.0, -512.0, 512.0, 512.0)
|
||||||
|
)
|
||||||
|
];
|
||||||
|
|
||||||
|
class _PaperAnimation extends Node {
|
||||||
|
_PaperAnimation() {
|
||||||
|
for (_PaperConfig config in _kPaperConfigs) {
|
||||||
|
|
||||||
|
final _PaperSheet sheet = new _PaperSheet(config);
|
||||||
|
final _PaperSheetShadow shadow = new _PaperSheetShadow(config);
|
||||||
|
|
||||||
|
addChild(shadow);
|
||||||
|
addChild(sheet);
|
||||||
|
_sheets.add(sheet);
|
||||||
|
|
||||||
|
shadow.constraints = <Constraint>[
|
||||||
|
new ConstraintRotationToNodeRotation(sheet),
|
||||||
|
new ConstraintPositionToNode(sheet, offset: const Offset(0.0, 10.0))
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<_PaperSheet> _sheets = <_PaperSheet>[];
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PaperConfig {
|
||||||
|
_PaperConfig({
|
||||||
|
this.color,
|
||||||
|
this.startPosition,
|
||||||
|
this.startRotation,
|
||||||
|
this.rotationSpeed,
|
||||||
|
this.parallaxDepth,
|
||||||
|
this.rect
|
||||||
|
});
|
||||||
|
|
||||||
|
final Color color;
|
||||||
|
final Point startPosition;
|
||||||
|
final double startRotation;
|
||||||
|
final double rotationSpeed;
|
||||||
|
final double parallaxDepth;
|
||||||
|
final Rect rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PaperSheet extends Node {
|
||||||
|
_PaperSheet(this._config) {
|
||||||
|
_paperPaint.color = _config.color;
|
||||||
|
|
||||||
|
position = _config.startPosition;
|
||||||
|
rotation = _config.startRotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
final _PaperConfig _config;
|
||||||
|
final Paint _paperPaint = new Paint();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void paint(Canvas canvas) {
|
||||||
|
canvas.drawRect(_config.rect, _paperPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void update(double dt) {
|
||||||
|
rotation += _config.rotationSpeed * dt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PaperSheetShadow extends Node {
|
||||||
|
_PaperSheetShadow(this._config) {
|
||||||
|
_paperPaint.color = Colors.black45;
|
||||||
|
_paperPaint.maskFilter = new MaskFilter.blur(BlurStyle.normal, 10.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
final _PaperConfig _config;
|
||||||
|
final Paint _paperPaint = new Paint();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void paint(Canvas canvas) {
|
||||||
|
canvas.drawRect(_config.rect, _paperPaint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _BackgroundBox extends Node {
|
||||||
|
final Paint _boxPaint = new Paint()..color = Colors.purple[500];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void paint(Canvas canvas) {
|
||||||
|
canvas.drawRect(new Rect.fromLTWH(0.0, 0.0, _kCanvasSize.width, _kCanvasSize.height), _boxPaint);
|
||||||
|
}
|
||||||
|
}
|
@ -5,9 +5,9 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
import 'demo.dart';
|
|
||||||
import 'drawer.dart';
|
import 'drawer.dart';
|
||||||
import 'section.dart';
|
import 'header.dart';
|
||||||
|
import 'item.dart';
|
||||||
|
|
||||||
import '../demo/buttons_demo.dart';
|
import '../demo/buttons_demo.dart';
|
||||||
import '../demo/cards_demo.dart';
|
import '../demo/cards_demo.dart';
|
||||||
@ -28,7 +28,6 @@ import '../demo/page_selector_demo.dart';
|
|||||||
import '../demo/persistent_bottom_sheet_demo.dart';
|
import '../demo/persistent_bottom_sheet_demo.dart';
|
||||||
import '../demo/progress_indicator_demo.dart';
|
import '../demo/progress_indicator_demo.dart';
|
||||||
import '../demo/toggle_controls_demo.dart';
|
import '../demo/toggle_controls_demo.dart';
|
||||||
import '../demo/scrolling_techniques_demo.dart';
|
|
||||||
import '../demo/slider_demo.dart';
|
import '../demo/slider_demo.dart';
|
||||||
import '../demo/snack_bar_demo.dart';
|
import '../demo/snack_bar_demo.dart';
|
||||||
import '../demo/scrollable_tabs_demo.dart';
|
import '../demo/scrollable_tabs_demo.dart';
|
||||||
@ -41,6 +40,8 @@ import '../demo/two_level_list_demo.dart';
|
|||||||
import '../demo/typography_demo.dart';
|
import '../demo/typography_demo.dart';
|
||||||
import '../demo/weather_demo.dart';
|
import '../demo/weather_demo.dart';
|
||||||
|
|
||||||
|
const double _kFlexibleSpaceMaxHeight = 256.0;
|
||||||
|
|
||||||
class GalleryHome extends StatefulWidget {
|
class GalleryHome extends StatefulWidget {
|
||||||
GalleryHome({ Key key }) : super(key: key);
|
GalleryHome({ Key key }) : super(key: key);
|
||||||
|
|
||||||
@ -49,109 +50,75 @@ class GalleryHome extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class GalleryHomeState extends State<GalleryHome> {
|
class GalleryHomeState extends State<GalleryHome> {
|
||||||
|
final Key _scrollableKey = new UniqueKey();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final double appBarHeight = 128.0;
|
final double statusBarHight = (MediaQuery.of(context)?.padding ?? EdgeInsets.zero).top;
|
||||||
|
|
||||||
return new Scaffold(
|
return new Scaffold(
|
||||||
drawer: new GalleryDrawer(),
|
drawer: new GalleryDrawer(),
|
||||||
appBar: new AppBar(
|
appBar: new AppBar(
|
||||||
expandedHeight: appBarHeight,
|
expandedHeight: _kFlexibleSpaceMaxHeight,
|
||||||
flexibleSpace: (BuildContext context) {
|
flexibleSpace: (BuildContext context) => new FlexibleSpaceBar(
|
||||||
return new Container(
|
image: new GalleryHeader(),
|
||||||
padding: const EdgeInsets.only(left: 64.0),
|
title: new Text("Flutter Gallery")
|
||||||
height: appBarHeight,
|
)
|
||||||
child: new Align(
|
|
||||||
alignment: const FractionalOffset(0.0, 1.0),
|
|
||||||
child: new Text('Flutter Gallery', style: Typography.white.headline)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
),
|
),
|
||||||
body: new Block(
|
scrollableKey: _scrollableKey,
|
||||||
padding: const EdgeInsets.all(4.0),
|
appBarBehavior: AppBarBehavior.under,
|
||||||
children: <Widget>[
|
body: new TwoLevelList(
|
||||||
new Row(
|
scrollablePadding: new EdgeInsets.only(top: _kFlexibleSpaceMaxHeight + statusBarHight),
|
||||||
|
key: _scrollableKey,
|
||||||
|
type: MaterialListType.oneLine,
|
||||||
|
scrollableKey: _scrollableKey,
|
||||||
|
items: <Widget>[
|
||||||
|
new TwoLevelSublist(
|
||||||
|
leading: new Icon(icon: Icons.star),
|
||||||
|
title: new Text("Demos"),
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
new GallerySection(
|
new GalleryItem(title: "Weather", builder: () => new WeatherDemo()),
|
||||||
title: 'Animation',
|
new GalleryItem(title: "Fitness", builder: () => new FitnessDemo()),
|
||||||
image: 'assets/section_animation.png',
|
|
||||||
colors: Colors.purple,
|
|
||||||
demos: <GalleryDemo>[
|
|
||||||
new GalleryDemo(title: 'Weather', builder: () => new WeatherDemo()),
|
|
||||||
new GalleryDemo(title: 'Fitness', builder: () => new FitnessDemo())
|
|
||||||
]
|
|
||||||
),
|
|
||||||
new GallerySection(
|
|
||||||
title: 'Style',
|
|
||||||
image: 'assets/section_style.png',
|
|
||||||
colors: Colors.green,
|
|
||||||
demos: <GalleryDemo>[
|
|
||||||
new GalleryDemo(title: 'Colors', builder: () => new ColorsDemo()),
|
|
||||||
new GalleryDemo(title: 'Typography', builder: () => new TypographyDemo())
|
|
||||||
]
|
|
||||||
)
|
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
new Row(
|
new TwoLevelSublist(
|
||||||
|
leading: new Icon(icon: Icons.extension),
|
||||||
|
title: new Text("Components"),
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
new GallerySection(
|
new GalleryItem(title: 'App Bar', builder: () => new FlexibleSpaceDemo()),
|
||||||
title: 'Layout',
|
new GalleryItem(title: 'Buttons', builder: () => new ButtonsDemo()),
|
||||||
image: 'assets/section_layout.png',
|
new GalleryItem(title: 'Buttons: Floating Action Button', builder: () => new TabsFabDemo()),
|
||||||
colors: Colors.pink
|
new GalleryItem(title: 'Cards', builder: () => new CardsDemo()),
|
||||||
),
|
new GalleryItem(title: 'Chips', builder: () => new ChipDemo()),
|
||||||
new GallerySection(
|
new GalleryItem(title: 'Date Picker', builder: () => new DatePickerDemo()),
|
||||||
title: 'Components',
|
new GalleryItem(title: 'Dialog', builder: () => new DialogDemo()),
|
||||||
image: 'assets/section_components.png',
|
new GalleryItem(title: 'Dropdown Button', builder: () => new DropDownDemo()),
|
||||||
colors: Colors.amber,
|
new GalleryItem(title: 'Expand/Collapse List Control', builder: () => new TwoLevelListDemo()),
|
||||||
demos: <GalleryDemo>[
|
new GalleryItem(title: 'Grid', builder: () => new GridListDemo()),
|
||||||
new GalleryDemo(title: 'App Bar', builder: () => new FlexibleSpaceDemo()),
|
new GalleryItem(title: 'Icons', builder: () => new IconsDemo()),
|
||||||
new GalleryDemo(title: 'Buttons', builder: () => new ButtonsDemo()),
|
new GalleryItem(title: 'Leave-behind List Items', builder: () => new LeaveBehindDemo()),
|
||||||
new GalleryDemo(title: 'Buttons: Floating Action Button', builder: () => new TabsFabDemo()),
|
new GalleryItem(title: 'List', builder: () => new ListDemo()),
|
||||||
new GalleryDemo(title: 'Cards', builder: () => new CardsDemo()),
|
new GalleryItem(title: 'Modal Bottom Sheet', builder: () => new ModalBottomSheetDemo()),
|
||||||
new GalleryDemo(title: 'Chips', builder: () => new ChipDemo()),
|
new GalleryItem(title: 'Menus', builder: () => new MenuDemo()),
|
||||||
new GalleryDemo(title: 'Date Picker', builder: () => new DatePickerDemo()),
|
new GalleryItem(title: 'Page Selector', builder: () => new PageSelectorDemo()),
|
||||||
new GalleryDemo(title: 'Dialog', builder: () => new DialogDemo()),
|
new GalleryItem(title: 'Persistent Bottom Sheet', builder: () => new PersistentBottomSheetDemo()),
|
||||||
new GalleryDemo(title: 'Dropdown Button', builder: () => new DropDownDemo()),
|
new GalleryItem(title: 'Progress Indicators', builder: () => new ProgressIndicatorDemo()),
|
||||||
new GalleryDemo(title: 'Expand/Collapse List Control', builder: () => new TwoLevelListDemo()),
|
new GalleryItem(title: 'Scrollable Tabs', builder: () => new ScrollableTabsDemo()),
|
||||||
new GalleryDemo(title: 'Grid', builder: () => new GridListDemo()),
|
new GalleryItem(title: 'Selection Controls', builder: () => new ToggleControlsDemo()),
|
||||||
new GalleryDemo(title: 'Icons', builder: () => new IconsDemo()),
|
new GalleryItem(title: 'Sliders', builder: () => new SliderDemo()),
|
||||||
new GalleryDemo(title: 'Leave-behind List Items', builder: () => new LeaveBehindDemo()),
|
new GalleryItem(title: 'SnackBar', builder: () => new SnackBarDemo()),
|
||||||
new GalleryDemo(title: 'List', builder: () => new ListDemo()),
|
new GalleryItem(title: 'Tabs', builder: () => new TabsDemo()),
|
||||||
new GalleryDemo(title: 'Modal Bottom Sheet', builder: () => new ModalBottomSheetDemo()),
|
new GalleryItem(title: 'Text Fields', builder: () => new TextFieldDemo()),
|
||||||
new GalleryDemo(title: 'Menus', builder: () => new MenuDemo()),
|
new GalleryItem(title: 'Time Picker', builder: () => new TimePickerDemo()),
|
||||||
new GalleryDemo(title: 'Page Selector', builder: () => new PageSelectorDemo()),
|
new GalleryItem(title: 'Tooltips', builder: () => new TooltipDemo()),
|
||||||
new GalleryDemo(title: 'Persistent Bottom Sheet', builder: () => new PersistentBottomSheetDemo()),
|
|
||||||
new GalleryDemo(title: 'Progress Indicators', builder: () => new ProgressIndicatorDemo()),
|
|
||||||
new GalleryDemo(title: 'Scrollable Tabs', builder: () => new ScrollableTabsDemo()),
|
|
||||||
new GalleryDemo(title: 'Selection Controls', builder: () => new ToggleControlsDemo()),
|
|
||||||
new GalleryDemo(title: 'Sliders', builder: () => new SliderDemo()),
|
|
||||||
new GalleryDemo(title: 'SnackBar', builder: () => new SnackBarDemo()),
|
|
||||||
new GalleryDemo(title: 'Tabs', builder: () => new TabsDemo()),
|
|
||||||
new GalleryDemo(title: 'Text Fields', builder: () => new TextFieldDemo()),
|
|
||||||
new GalleryDemo(title: 'Time Picker', builder: () => new TimePickerDemo()),
|
|
||||||
new GalleryDemo(title: 'Tooltips', builder: () => new TooltipDemo())
|
|
||||||
]
|
|
||||||
)
|
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
new Row(
|
new TwoLevelSublist(
|
||||||
|
leading: new Icon(icon: Icons.color_lens),
|
||||||
|
title: new Text("Style"),
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
new GallerySection(
|
new GalleryItem(title: 'Colors', builder: () => new ColorsDemo()),
|
||||||
title: 'Patterns',
|
new GalleryItem(title: 'Typography', builder: () => new TypographyDemo()),
|
||||||
image: 'assets/section_patterns.png',
|
|
||||||
colors: Colors.cyan,
|
|
||||||
demos: <GalleryDemo>[
|
|
||||||
new GalleryDemo(title: 'Scrolling Techniques', builder: () => new ScrollingTechniquesDemo())
|
|
||||||
]
|
|
||||||
),
|
|
||||||
new GallerySection(
|
|
||||||
title: 'Usability',
|
|
||||||
image: 'assets/section_usability.png',
|
|
||||||
colors: Colors.lightGreen,
|
|
||||||
demos: <GalleryDemo>[
|
|
||||||
new GalleryDemo(title: 'Tooltips', builder: () => new TooltipDemo())
|
|
||||||
]
|
|
||||||
)
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
28
examples/material_gallery/lib/gallery/item.dart
Normal file
28
examples/material_gallery/lib/gallery/item.dart
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
typedef Widget GalleryDemoBuilder();
|
||||||
|
|
||||||
|
class GalleryItem extends StatelessWidget {
|
||||||
|
GalleryItem({ this.title, this.icon, this.builder });
|
||||||
|
|
||||||
|
final String title;
|
||||||
|
final IconData icon;
|
||||||
|
final GalleryDemoBuilder builder;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
Widget leading = icon == null ? new Container() : new Icon(icon: icon);
|
||||||
|
|
||||||
|
return new TwoLevelListItem(
|
||||||
|
leading: leading,
|
||||||
|
title: new Text(title),
|
||||||
|
onTap: () {
|
||||||
|
if (builder != null) {
|
||||||
|
Navigator.push(context, new MaterialPageRoute<Null>(
|
||||||
|
builder: (BuildContext context) => builder()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,107 +0,0 @@
|
|||||||
// 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 'demo.dart';
|
|
||||||
|
|
||||||
class GallerySection extends StatelessWidget {
|
|
||||||
GallerySection({ this.title, this.image, this.colors, this.demos });
|
|
||||||
|
|
||||||
final String title;
|
|
||||||
final String image;
|
|
||||||
final Map<int, Color> colors;
|
|
||||||
final List<GalleryDemo> demos;
|
|
||||||
|
|
||||||
void showDemo(GalleryDemo demo, BuildContext context, ThemeData theme) {
|
|
||||||
Navigator.push(context, new MaterialPageRoute<Null>(
|
|
||||||
builder: (BuildContext context) {
|
|
||||||
Widget child = (demo.builder == null) ? null : demo.builder();
|
|
||||||
return new Theme(data: theme, child: child);
|
|
||||||
}
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
void showDemos(BuildContext context) {
|
|
||||||
final double statusBarHeight = MediaQuery.of(context).padding.top;
|
|
||||||
final ThemeData theme = new ThemeData(
|
|
||||||
brightness: Theme.of(context).brightness,
|
|
||||||
primarySwatch: colors
|
|
||||||
);
|
|
||||||
final double appBarHeight = 200.0;
|
|
||||||
final Key scrollableKey = new ValueKey<String>(title); // assume section titles differ
|
|
||||||
Navigator.push(context, new MaterialPageRoute<Null>(
|
|
||||||
builder: (BuildContext context) {
|
|
||||||
return new Theme(
|
|
||||||
data: theme,
|
|
||||||
child: new Scaffold(
|
|
||||||
appBarBehavior: AppBarBehavior.under,
|
|
||||||
scrollableKey: scrollableKey,
|
|
||||||
appBar: new AppBar(
|
|
||||||
expandedHeight: appBarHeight,
|
|
||||||
flexibleSpace: (BuildContext context) => new FlexibleSpaceBar(title: new Text(title))
|
|
||||||
),
|
|
||||||
body: new Material(
|
|
||||||
child: new MaterialList(
|
|
||||||
scrollableKey: scrollableKey,
|
|
||||||
scrollablePadding: new EdgeInsets.only(top: appBarHeight + statusBarHeight),
|
|
||||||
type: MaterialListType.oneLine,
|
|
||||||
children: (demos ?? const <GalleryDemo>[]).map((GalleryDemo demo) {
|
|
||||||
return new ListItem(
|
|
||||||
title: new Text(demo.title),
|
|
||||||
onTap: () { showDemo(demo, context, theme); }
|
|
||||||
);
|
|
||||||
})
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build (BuildContext context) {
|
|
||||||
final ThemeData theme = new ThemeData(
|
|
||||||
brightness: Theme.of(context).brightness,
|
|
||||||
primarySwatch: colors
|
|
||||||
);
|
|
||||||
final TextStyle titleTextStyle = theme.textTheme.title.copyWith(
|
|
||||||
color: Colors.white
|
|
||||||
);
|
|
||||||
return new Flexible(
|
|
||||||
child: new GestureDetector(
|
|
||||||
behavior: HitTestBehavior.opaque,
|
|
||||||
onTap: () { showDemos(context); },
|
|
||||||
child: new Container(
|
|
||||||
height: 256.0,
|
|
||||||
margin: const EdgeInsets.all(4.0),
|
|
||||||
decoration: new BoxDecoration(backgroundColor: theme.primaryColor),
|
|
||||||
child: new Column(
|
|
||||||
children: <Widget>[
|
|
||||||
new Flexible(
|
|
||||||
child: new Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
|
||||||
child: new AssetImage(
|
|
||||||
name: image,
|
|
||||||
alignment: const FractionalOffset(0.5, 0.5),
|
|
||||||
fit: ImageFit.contain
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
new Padding(
|
|
||||||
padding: const EdgeInsets.all(16.0),
|
|
||||||
child: new Align(
|
|
||||||
alignment: const FractionalOffset(0.0, 1.0),
|
|
||||||
child: new Text(title, style: titleTextStyle)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,4 +7,4 @@ dependencies:
|
|||||||
path: ../../packages/flutter
|
path: ../../packages/flutter
|
||||||
flutter_sprites:
|
flutter_sprites:
|
||||||
path: ../../packages/flutter_sprites
|
path: ../../packages/flutter_sprites
|
||||||
flutter_gallery_assets: '0.0.9'
|
flutter_gallery_assets: '0.0.12'
|
||||||
|
@ -154,14 +154,25 @@ class _TwoLevelSublistState extends State<TwoLevelSublist> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class TwoLevelList extends StatelessWidget {
|
class TwoLevelList extends StatelessWidget {
|
||||||
TwoLevelList({ Key key, this.scrollableKey, this.items, this.type: MaterialListType.twoLine }) : super(key: key);
|
TwoLevelList({
|
||||||
|
Key key,
|
||||||
|
this.scrollableKey,
|
||||||
|
this.items,
|
||||||
|
this.type: MaterialListType.twoLine,
|
||||||
|
this.scrollablePadding
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
final List<Widget> items;
|
final List<Widget> items;
|
||||||
final MaterialListType type;
|
final MaterialListType type;
|
||||||
final Key scrollableKey;
|
final Key scrollableKey;
|
||||||
|
final EdgeInsets scrollablePadding;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return new Block(children: KeyedSubtree.ensureUniqueKeysForList(items), scrollableKey: scrollableKey);
|
return new Block(
|
||||||
|
padding: scrollablePadding,
|
||||||
|
children: KeyedSubtree.ensureUniqueKeysForList(items),
|
||||||
|
scrollableKey: scrollableKey
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,29 @@ class ConstraintRotationToMovement extends Constraint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A [Constraint] that copies a node's rotation, optionally with [dampening].
|
||||||
|
class ConstraintRotationToNodeRotation extends Constraint {
|
||||||
|
/// Creates a new constraint that copies a node's rotation, optionally
|
||||||
|
/// with a [baseRotation] added and using [dampening].
|
||||||
|
ConstraintRotationToNodeRotation(this.targetNode, { this.baseRotation: 0.0, this.dampening });
|
||||||
|
|
||||||
|
/// The node to copy the rotation from
|
||||||
|
final Node targetNode;
|
||||||
|
|
||||||
|
/// The base rotation will be added to the rotation that copied from the targetNode
|
||||||
|
final double baseRotation;
|
||||||
|
|
||||||
|
/// The filter factor used when constraining the rotation of the node. Valid
|
||||||
|
/// values are in the range 0.0 to 1.0
|
||||||
|
final double dampening;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void constrain(Node node, double dt) {
|
||||||
|
double target = targetNode.rotation + baseRotation;
|
||||||
|
node.rotation = _dampenRotation(node.rotation, target, dampening);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A [Constraint] that rotates a node to point towards another node. The target
|
/// A [Constraint] that rotates a node to point towards another node. The target
|
||||||
/// node is allowed to have a different parent, but they must be in the same
|
/// node is allowed to have a different parent, but they must be in the same
|
||||||
/// [SpriteBox].
|
/// [SpriteBox].
|
||||||
|
Loading…
x
Reference in New Issue
Block a user