Commit 475d5a45 authored by Hans Muller's avatar Hans Muller

remove spurious copy of the material_gallery directory (#3806)

parent cc931708
.DS_Store
.atom/
.idea
.packages
.pub/
build/
ios/.generated/
packages
pubspec.lock
# Flutter gallery
Demo app for the Material Design widgets and other features provided by Flutter.
## Icon
Icon was generated using Android Asset Studio:
https://romannurik.github.io/AndroidAssetStudio/icons-launcher.html#foreground.type=image&foreground.space.trim=0&foreground.space.pad=0.1&foreColor=607d8b%2C0&crop=0&backgroundShape=square&backColor=ffffff%2C100&effects=none
From the Flutter Logo:
https://github.com/flutter/website/blob/master/_includes/logo.html
which appears to be CC-BY 4.0.
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2015 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="io.flutter.MaterialGallery" android:versionCode="1" android:versionName="0.0.1">
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.INTERNET"/>
<application android:icon="@mipmap/ic_launcher" android:label="Flutter gallery" android:name="org.domokit.sky.shell.SkyApplication">
<activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize" android:hardwareAccelerated="true" android:launchMode="singleTop" android:name="org.domokit.sky.shell.SkyActivity" android:theme="@android:style/Theme.Black.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
name: flutter_gallery
uses-material-design: true
assets:
- assets/flutter_logo.png
- assets/section_animation.png
- assets/section_style.png
- assets/section_layout.png
- assets/section_components.png
- assets/section_patterns.png
- assets/section_usability.png
- packages/flutter_gallery_assets/ali_connors.png
- packages/flutter_gallery_assets/sun.png
- packages/flutter_gallery_assets/clouds-0.png
- packages/flutter_gallery_assets/clouds-1.png
- packages/flutter_gallery_assets/ray.png
- packages/flutter_gallery_assets/sun.png
- packages/flutter_gallery_assets/weathersprites.json
- packages/flutter_gallery_assets/weathersprites.png
- packages/flutter_gallery_assets/icon-sun.png
- packages/flutter_gallery_assets/icon-rain.png
- packages/flutter_gallery_assets/icon-snow.png
- packages/flutter_gallery_assets/kangaroo_valley_safari.png
- packages/flutter_gallery_assets/top_10_australian_beaches.png
- packages/flutter_gallery_assets/jumpingjack.json
- packages/flutter_gallery_assets/jumpingjack.png
- packages/flutter_gallery_assets/grain.png
- packages/flutter_gallery_assets/fancylines.png
- packages/flutter_gallery_assets/landscape_0.jpg
- packages/flutter_gallery_assets/landscape_1.jpg
- packages/flutter_gallery_assets/landscape_2.jpg
- packages/flutter_gallery_assets/landscape_3.jpg
- packages/flutter_gallery_assets/landscape_4.jpg
- packages/flutter_gallery_assets/landscape_5.jpg
- packages/flutter_gallery_assets/landscape_6.jpg
- packages/flutter_gallery_assets/landscape_7.jpg
- packages/flutter_gallery_assets/landscape_8.jpg
- packages/flutter_gallery_assets/landscape_9.jpg
- packages/flutter_gallery_assets/landscape_10.jpg
- packages/flutter_gallery_assets/landscape_11.jpg
- packages/flutter_gallery_assets/shadow.png
- lib/gallery/example_code.dart
{
"images" : [
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-Small@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-Small@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-Small-40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-Small-40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-60@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-Small.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-Small@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-Small-40.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-Small-40@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-76.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-83.5@2x.png",
"scale" : "2x"
},
{
"size" : "16x16",
"idiom" : "mac",
"filename" : "icon_16x16.png",
"scale" : "1x"
},
{
"size" : "16x16",
"idiom" : "mac",
"filename" : "icon_16x16@2x.png",
"scale" : "2x"
},
{
"size" : "32x32",
"idiom" : "mac",
"filename" : "icon_32x32.png",
"scale" : "1x"
},
{
"size" : "32x32",
"idiom" : "mac",
"filename" : "icon_32x32@2x.png",
"scale" : "2x"
},
{
"size" : "128x128",
"idiom" : "mac",
"filename" : "icon_128x128.png",
"scale" : "1x"
},
{
"size" : "128x128",
"idiom" : "mac",
"filename" : "icon_128x128@2x.png",
"scale" : "2x"
},
{
"size" : "256x256",
"idiom" : "mac",
"filename" : "icon_256x256.png",
"scale" : "1x"
},
{
"size" : "256x256",
"idiom" : "mac",
"filename" : "icon_256x256@2x.png",
"scale" : "2x"
},
{
"size" : "512x512",
"idiom" : "mac",
"filename" : "icon_512x512.png",
"scale" : "1x"
},
{
"size" : "512x512",
"idiom" : "mac",
"filename" : "icon_512x512@2x.png",
"scale" : "2x"
}
]
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>Runner</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.materialgallery</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Flutter gallery</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
<viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>
// 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.
export 'buttons_demo.dart';
export 'cards_demo.dart';
export 'chip_demo.dart';
export 'colors_demo.dart';
export 'data_table_demo.dart';
export 'date_picker_demo.dart';
export 'dialog_demo.dart';
export 'drawing_demo.dart';
export 'drop_down_demo.dart';
export 'fitness_demo.dart';
export 'flexible_space_demo.dart';
export 'grid_list_demo.dart';
export 'icons_demo.dart';
export 'leave_behind_demo.dart';
export 'list_demo.dart';
export 'menu_demo.dart';
export 'modal_bottom_sheet_demo.dart';
export 'overscroll_demo.dart';
export 'page_selector_demo.dart';
export 'persistent_bottom_sheet_demo.dart';
export 'progress_indicator_demo.dart';
export 'scrollable_tabs_demo.dart';
export 'selection_controls_demo.dart';
export 'slider_demo.dart';
export 'snack_bar_demo.dart';
export 'tabs_demo.dart';
export 'tabs_fab_demo.dart';
export 'text_field_demo.dart';
export 'time_picker_demo.dart';
export 'tooltip_demo.dart';
export 'two_level_list_demo.dart';
export 'typography_demo.dart';
export 'weather_demo.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/material.dart';
import '../gallery/demo.dart';
const String _raisedText =
"# Raised buttons\n"
"Raised buttons add dimension to mostly flat layouts. They emphasize "
"functions on busy or wide spaces.";
const String _raisedCode = 'buttons_raised';
const String _flatText =
"# Flat buttons\n"
"A flat button displays an ink splash on press "
"but does not lift. Use flat buttons on toolbars, in dialogs and "
"inline with padding";
const String _flatCode = 'buttons_flat';
const String _dropdownText =
"# Dropdown buttons\n"
"A dropdown button displays a menu that's used to select a value from a "
"small set of values. The button displays the current value and a down "
"arrow.";
const String _dropdownCode = 'buttons_dropdown';
const String _iconText =
"IconButtons are appropriate for toggle buttons that allow a single choice to be "
"selected or deselected, such as adding or removing an item's star.";
const String _iconCode = 'buttons_icon';
const String _actionText =
"# Floating action buttons\n"
"Floating action buttons are used for a promoted action. They are "
"distinguished by a circled icon floating above the UI and can have motion "
"behaviors that include morphing, launching, and a transferring anchor "
"point.";
const String _actionCode = 'buttons_action';
class ButtonsDemo extends StatefulWidget {
static const String routeName = '/buttons';
@override
_ButtonsDemoState createState() => new _ButtonsDemoState();
}
class _ButtonsDemoState extends State<ButtonsDemo> {
@override
Widget build(BuildContext context) {
List<ComponentDemoTabData> demos = <ComponentDemoTabData>[
new ComponentDemoTabData(
tabName: 'RAISED',
description: _raisedText,
widget: buildRaisedButton(),
exampleCodeTag: _raisedCode
),
new ComponentDemoTabData(
tabName: 'FLAT',
description: _flatText,
widget: buildFlatButton(),
exampleCodeTag: _flatCode
),
new ComponentDemoTabData(
tabName: 'DROPDOWN',
description: _dropdownText,
widget: buildDropdownButton(),
exampleCodeTag: _dropdownCode
),
new ComponentDemoTabData(
tabName: 'ICON',
description: _iconText,
widget: buildIconButton(),
exampleCodeTag: _iconCode
),
new ComponentDemoTabData(
tabName: 'ACTION',
description: _actionText,
widget: buildActionButton(),
exampleCodeTag: _actionCode
),
];
return new TabbedComponentDemoScaffold(
title: 'Buttons',
demos: demos
);
}
Widget buildRaisedButton() {
return new Align(
alignment: new FractionalOffset(0.5, 0.4),
child: new ButtonBar(
alignment: MainAxisAlignment.collapse,
children: <Widget>[
new RaisedButton(
child: new Text('RAISED BUTTON'),
onPressed: () {
// Perform some action
}
),
new RaisedButton(
child: new Text('DISABLED')
)
]
)
);
}
Widget buildFlatButton() {
return new Align(
alignment: new FractionalOffset(0.5, 0.4),
child: new ButtonBar(
alignment: MainAxisAlignment.collapse,
children: <Widget>[
new FlatButton(
child: new Text('FLAT BUTTON'),
onPressed: () {
// Perform some action
}
),
new FlatButton(
child: new Text('DISABLED')
)
]
)
);
}
String dropdownValue = 'Free';
Widget buildDropdownButton() {
return new Align(
alignment: new FractionalOffset(0.5, 0.4),
child: new DropDownButton<String>(
value: dropdownValue,
onChanged: (String newValue) {
setState(() {
if (newValue != null)
dropdownValue = newValue;
});
},
items: <String>['One', 'Two', 'Free', 'Four']
.map((String value) {
return new DropDownMenuItem<String>(
value: value,
child: new Text(value));
})
.toList()
)
);
}
bool iconButtonToggle = false;
Widget buildIconButton() {
return new Align(
alignment: new FractionalOffset(0.5, 0.4),
child: new Row(
mainAxisAlignment: MainAxisAlignment.collapse,
children: <Widget>[
new IconButton(
icon: Icons.thumb_up,
onPressed: () {
setState(() => iconButtonToggle = !iconButtonToggle);
},
color: iconButtonToggle ? Theme.of(context).primaryColor : null
),
new IconButton(
icon: Icons.thumb_up
)
]
.map((Widget button) => new SizedBox(width: 64.0, height: 64.0, child: button))
.toList()
)
);
}
Widget buildActionButton() {
return new Align(
alignment: new FractionalOffset(0.5, 0.4),
child: new FloatingActionButton(
child: new Icon(icon: Icons.add),
onPressed: () {
// Perform some action
}
)
);
}
}
// 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';
class TravelDestination {
const TravelDestination({ this.assetName, this.title, this.description });
final String assetName;
final String title;
final List<String> description;
bool get isValid => assetName != null && title != null && description?.length == 3;
}
final List<TravelDestination> destinations = <TravelDestination>[
const TravelDestination(
assetName: 'packages/flutter_gallery_assets/top_10_australian_beaches.png',
title: 'Top 10 Australian beaches',
description: const <String>[
'Number 10',
'Whitehaven Beach',
'Whitsunday Island, Whitsunday Islands'
]
),
const TravelDestination(
assetName: 'packages/flutter_gallery_assets/kangaroo_valley_safari.png',
title: 'Kangaroo Valley Safari',
description: const <String>[
'2031 Moss Vale Road',
'Kangaroo Valley 2577',
'New South Wales'
]
)
];
class TravelDestinationItem extends StatelessWidget {
TravelDestinationItem({ Key key, this.destination }) : super(key: key) {
assert(destination != null && destination.isValid);
}
static final double height = 328.0;
final TravelDestination destination;
@override
Widget build(BuildContext context) {
ThemeData theme = Theme.of(context);
TextStyle titleStyle = theme.textTheme.headline.copyWith(color: Colors.white);
TextStyle descriptionStyle = theme.textTheme.subhead;
return new SizedBox(
height: height,
child: new Card(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
// photo and title
new SizedBox(
height: 184.0,
child: new Stack(
children: <Widget>[
new Positioned(
left: 0.0,
top: 0.0,
bottom: 0.0,
right: 0.0,
child: new AssetImage(
name: destination.assetName,
fit: ImageFit.cover
)
),
new Positioned(
bottom: 16.0,
left: 16.0,
child: new Text(destination.title, style: titleStyle)
)
]
)
),
// description and share/expore buttons
new Flexible(
child: new Padding(
padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 0.0),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
// three line description
new Text(destination.description[0], style: descriptionStyle),
new Text(destination.description[1], style: descriptionStyle),
new Text(destination.description[2], style: descriptionStyle),
]
)
)
),
// share, explore buttons
// TODO(abarth): The theme and the bar should be part of card.
new ButtonTheme.footer(
child: new ButtonBar(
alignment: MainAxisAlignment.start,
children: <Widget>[
new FlatButton(
child: new Text('SHARE'),
onPressed: () { /* do nothing */ }
),
new FlatButton(
child: new Text('EXPLORE'),
onPressed: () { /* do nothing */ }
),
]
)
),
]
)
)
);
}
}
class CardsDemo extends StatelessWidget {
static const String routeName = '/cards';
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Travel stream')
),
body: new ScrollableList(
itemExtent: TravelDestinationItem.height,
padding: const EdgeInsets.only(top: 8.0, left: 8.0, right: 8.0),
children: destinations.map((TravelDestination destination) {
return new Container(
margin: const EdgeInsets.only(bottom: 8.0),
child: new TravelDestinationItem(destination: destination)
);
})
.toList()
)
);
}
}
// Copyright 2015 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';
class ChipDemo extends StatefulWidget {
static const String routeName = '/chip';
@override
_ChipDemoState createState() => new _ChipDemoState();
}
class _ChipDemoState extends State<ChipDemo> {
bool _showBananas = true;
void _deleteBananas() {
setState(() {
_showBananas = false;
});
}
@override
Widget build(BuildContext context) {
List<Widget> chips = <Widget>[
new Chip(
label: new Text('Apple')
),
new Chip(
avatar: new CircleAvatar(child: new Text('B')),
label: new Text('Blueberry')
),
];
if (_showBananas) {
chips.add(new Chip(
label: new Text('Bananas'),
onDeleted: _deleteBananas
));
}
return new Scaffold(
appBar: new AppBar(title: new Text('Chips')),
body: new Block(
children: chips.map((Widget widget) {
return new Container(
height: 100.0,
child: new Center(child: widget)
);
}).toList()
)
);
}
}
// 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';
const double kColorItemHeight = 48.0;
class ColorSwatch {
const ColorSwatch({ this.name, this.colors, this.accentColors, this.threshold: 900});
final String name;
final Map<int, Color> colors;
final Map<int, Color> accentColors;
final int threshold; // titles for indices > threshold are white, otherwise black
bool get isValid => this.name != null && this.colors != null && threshold != null;
}
const List<ColorSwatch> colorSwatches = const <ColorSwatch>[
const ColorSwatch(name: 'RED', colors: Colors.red, accentColors: Colors.redAccent, threshold: 300),
const ColorSwatch(name: 'PINK', colors: Colors.pink, accentColors: Colors.pinkAccent, threshold: 200),
const ColorSwatch(name: 'PURPLE', colors: Colors.purple, accentColors: Colors.purpleAccent, threshold: 200),
const ColorSwatch(name: 'DEEP PURPLE', colors: Colors.deepPurple, accentColors: Colors.deepPurpleAccent, threshold: 200),
const ColorSwatch(name: 'INDIGO', colors: Colors.indigo, accentColors: Colors.indigoAccent, threshold: 200),
const ColorSwatch(name: 'BLUE', colors: Colors.blue, accentColors: Colors.blueAccent, threshold: 400),
const ColorSwatch(name: 'LIGHT BLUE', colors: Colors.lightBlue, accentColors: Colors.lightBlueAccent, threshold: 500),
const ColorSwatch(name: 'CYAN', colors: Colors.cyan, accentColors: Colors.cyanAccent, threshold: 600),
const ColorSwatch(name: 'TEAL', colors: Colors.teal, accentColors: Colors.tealAccent, threshold: 400),
const ColorSwatch(name: 'GREEN', colors: Colors.green, accentColors: Colors.greenAccent, threshold: 500),
const ColorSwatch(name: 'LIGHT GREEN', colors: Colors.lightGreen, accentColors: Colors.lightGreenAccent, threshold: 600),
const ColorSwatch(name: 'LIME', colors: Colors.lime, accentColors: Colors.limeAccent, threshold: 800),
const ColorSwatch(name: 'YELLOW', colors: Colors.yellow, accentColors: Colors.yellowAccent),
const ColorSwatch(name: 'AMBER', colors: Colors.amber, accentColors: Colors.amberAccent),
const ColorSwatch(name: 'ORANGE', colors: Colors.orange, accentColors: Colors.orangeAccent, threshold: 700),
const ColorSwatch(name: 'DEEP ORANGE', colors: Colors.deepOrange, accentColors: Colors.deepOrangeAccent, threshold: 400),
const ColorSwatch(name: 'BROWN', colors: Colors.brown, threshold: 200),
const ColorSwatch(name: 'GREY', colors: Colors.grey, threshold: 500),
const ColorSwatch(name: 'BLUE GREY', colors: Colors.blueGrey, threshold: 500)
];
class ColorItem extends StatelessWidget {
ColorItem({ Key key, this.index, this.color, this.prefix: '' }) : super(key: key) {
assert(index != null);
assert(color != null);
assert(prefix != null);
}
final int index;
final Color color;
final String prefix;
String colorString() => "#${color.value.toRadixString(16).padLeft(8, '0').toUpperCase()}";
@override
Widget build(BuildContext context) {
return new Container(
height: kColorItemHeight,
padding: const EdgeInsets.symmetric(horizontal: 16.0),
decoration: new BoxDecoration(backgroundColor: color),
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Text('$prefix$index'),
new Text(colorString())
]
)
);
}
}
class ColorSwatchTabView extends StatelessWidget {
ColorSwatchTabView({ Key key, this.swatch }) : super(key: key) {
assert(swatch != null && swatch.isValid);
}
final ColorSwatch swatch;
final TextStyle blackTextStyle = Typography.black.body1;
final TextStyle whiteTextStyle = Typography.white.body1;
@override
Widget build(BuildContext context) {
List<Widget> colorItems = swatch.colors.keys.map((int index) {
return new DefaultTextStyle(
style: index > swatch.threshold ? whiteTextStyle : blackTextStyle,
child: new ColorItem(index: index, color: swatch.colors[index])
);
})
.toList();
if (swatch.accentColors != null) {
colorItems.addAll(swatch.accentColors.keys.map((int index) {
return new DefaultTextStyle(
style: index > swatch.threshold ? whiteTextStyle : blackTextStyle,
child: new ColorItem(index: index, color: swatch.accentColors[index], prefix: 'A')
);
})
.toList());
}
return new ScrollableList(
itemExtent: kColorItemHeight,
children: colorItems
);
}
}
class ColorsDemo extends StatelessWidget {
static const String routeName = '/colors';
@override
Widget build(BuildContext context) {
return new TabBarSelection<ColorSwatch>(
values: colorSwatches,
child: new Scaffold(
appBar: new AppBar(
elevation: 0,
title: new Text('Colors'),
tabBar: new TabBar<ColorSwatch>(
isScrollable: true,
labels: new Map<ColorSwatch, TabLabel>.fromIterable(colorSwatches, value: (ColorSwatch swatch) {
return new TabLabel(text: swatch.name);
})
)
),
body: new TabBarView<ColorSwatch>(
children: colorSwatches.map((ColorSwatch swatch) {
return new ColorSwatchTabView(swatch: swatch);
})
.toList()
)
)
);
}
}
// 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/rendering.dart';
class Desert {
Desert(this.name, this.calories, this.fat, this.carbs, this.protein, this.sodium, this.calcium, this.iron);
final String name;
final int calories;
final double fat;
final int carbs;
final double protein;
final int sodium;
final int calcium;
final int iron;
bool selected = false;
}
class DataTableDemo extends StatefulWidget {
static const String routeName = '/data-table';
@override
_DataTableDemoState createState() => new _DataTableDemoState();
}
class _DataTableDemoState extends State<DataTableDemo> {
int _sortColumnIndex;
bool _sortAscending = true;
final List<Desert> _deserts = <Desert>[
new Desert('Frozen yogurt', 159, 6.0, 24, 4.0, 87, 14, 1),
new Desert('Ice cream sandwich', 237, 9.0, 37, 4.3, 129, 8, 1),
new Desert('Eclair', 262, 16.0, 24, 6.0, 337, 6, 7),
new Desert('Cupcake', 305, 3.7, 67, 4.3, 413, 3, 8),
new Desert('Gingerbread', 356, 16.0, 49, 3.9, 327, 7, 16),
new Desert('Jelly bean', 375, 0.0, 94, 0.0, 50, 0, 0),
new Desert('Lollipop', 392, 0.2, 98, 0.0, 38, 0, 2),
new Desert('Honeycomb', 408, 3.2, 87, 6.5, 562, 0, 45),
new Desert('Donut', 452, 25.0, 51, 4.9, 326, 2, 22),
new Desert('KitKat', 518, 26.0, 65, 7.0, 54, 12, 6),
];
void _sort/*<T>*/(Comparable<dynamic/*=T*/> getField(Desert d), int columnIndex, bool ascending) {
setState(() {
_deserts.sort((Desert a, Desert b) {
if (!ascending) {
final Desert c = a;
a = b;
b = c;
}
final Comparable<dynamic/*=T*/> aValue = getField(a);
final Comparable<dynamic/*=T*/> bValue = getField(b);
return Comparable.compare(aValue, bValue);
});
_sortColumnIndex = columnIndex;
_sortAscending = ascending;
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text('Data tables')),
body: new Block(
children: <Widget>[
new Material(
child: new IntrinsicHeight(
child: new Block(
scrollDirection: Axis.horizontal,
children: <Widget>[
new DataTable(
sortColumnIndex: _sortColumnIndex,
sortAscending: _sortAscending,
columns: <DataColumn>[
new DataColumn(
label: new Text('Dessert (100g serving)'),
onSort: (int columnIndex, bool ascending) => _sort/*<String>*/((Desert d) => d.name, columnIndex, ascending)
),
new DataColumn(
label: new Text('Calories'),
tooltip: 'The total amount of food energy in the given serving size.',
numeric: true,
onSort: (int columnIndex, bool ascending) => _sort/*<num>*/((Desert d) => d.calories, columnIndex, ascending)
),
new DataColumn(
label: new Text('Fat (g)'),
numeric: true,
onSort: (int columnIndex, bool ascending) => _sort/*<num>*/((Desert d) => d.fat, columnIndex, ascending)
),
new DataColumn(
label: new Text('Carbs (g)'),
numeric: true,
onSort: (int columnIndex, bool ascending) => _sort/*<num>*/((Desert d) => d.carbs, columnIndex, ascending)
),
new DataColumn(
label: new Text('Protein (g)'),
numeric: true,
onSort: (int columnIndex, bool ascending) => _sort/*<num>*/((Desert d) => d.protein, columnIndex, ascending)
),
new DataColumn(
label: new Text('Sodium (mg)'),
numeric: true,
onSort: (int columnIndex, bool ascending) => _sort/*<num>*/((Desert d) => d.sodium, columnIndex, ascending)
),
new DataColumn(
label: new Text('Calcium (%)'),
tooltip: 'The amount of calcium as a percentage of the recommended daily amount.',
numeric: true,
onSort: (int columnIndex, bool ascending) => _sort/*<num>*/((Desert d) => d.calcium, columnIndex, ascending)
),
new DataColumn(
label: new Text('Iron (%)'),
numeric: true,
onSort: (int columnIndex, bool ascending) => _sort/*<num>*/((Desert d) => d.iron, columnIndex, ascending)
),
],
rows: _deserts.map/*<DataRow>*/((Desert desert) {
return new DataRow(
key: new ValueKey<Desert>(desert),
selected: desert.selected,
onSelectChanged: (bool selected) { setState(() { desert.selected = selected; }); },
cells: <DataCell>[
new DataCell(new Text('${desert.name}')),
new DataCell(new Text('${desert.calories}')),
new DataCell(new Text('${desert.fat.toStringAsFixed(1)}')),
new DataCell(new Text('${desert.carbs}')),
new DataCell(new Text('${desert.protein.toStringAsFixed(1)}')),
new DataCell(new Text('${desert.sodium}')),
new DataCell(new Text('${desert.calcium}%')),
new DataCell(new Text('${desert.iron}%')),
]
);
}).toList(growable: false)
)
]
)
)
)
]
)
);
}
}
// Copyright 2015 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 'dart:async';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class DatePickerDemo extends StatefulWidget {
static const String routeName = '/date-picker';
@override
_DatePickerDemoState createState() => new _DatePickerDemoState();
}
class _DatePickerDemoState extends State<DatePickerDemo> {
DateTime _selectedDate = new DateTime.now();
Future<Null> _handleSelectDate() async {
DateTime picked = await showDatePicker(
context: context,
initialDate: _selectedDate,
firstDate: new DateTime(2015, 8),
lastDate: new DateTime(2101)
);
if (picked != _selectedDate) {
setState(() {
_selectedDate = picked;
});
}
}
@override
Widget build(BuildContext context) {
return
new Scaffold(
appBar: new AppBar(title: new Text('Date picker')),
body: new Column(
children: <Widget>[
new Text(new DateFormat.yMMMd().format(_selectedDate)),
new SizedBox(height: 20.0),
new RaisedButton(
onPressed: _handleSelectDate,
child: new Text('SELECT DATE')
),
],
mainAxisAlignment: MainAxisAlignment.center
)
);
}
}
// 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 'full_screen_dialog_demo.dart';
enum DialogDemoAction {
cancel,
discard,
disagree,
agree,
}
const String _alertWithoutTitleText = "Discard draft?";
const String _alertWithTitleText =
"Let Google help apps determine location. This means sending anyonmous location "
"data to Google, even when no apps are running.";
class DialogDemoItem extends StatelessWidget {
DialogDemoItem({ Key key, this.icon, this.color, this.text, this.onPressed }) : super(key: key);
final IconData icon;
final Color color;
final String text;
final VoidCallback onPressed;
@override
Widget build(BuildContext context) {
return new InkWell(
onTap: onPressed,
child: new Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Icon(
size: 36.0,
icon: icon,
color: color
),
new Padding(
padding: const EdgeInsets.only(left: 16.0),
child: new Text(text)
)
]
)
)
);
}
}
class DialogDemo extends StatefulWidget {
static const String routeName = '/dialog';
@override
DialogDemoState createState() => new DialogDemoState();
}
class DialogDemoState extends State<DialogDemo> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
void showDemoDialog/*<T>*/({ BuildContext context, Dialog dialog }) {
showDialog/*<T>*/(
context: context,
child: dialog
)
.then((dynamic/*=T*/ value) { // The value passed to Navigator.pop() or null.
if (value != null) {
_scaffoldKey.currentState.showSnackBar(new SnackBar(
content: new Text('You selected: $value')
));
}
});
}
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final TextStyle dialogTextStyle = theme.textTheme.subhead.copyWith(color: theme.textTheme.caption.color);
return new Scaffold(
key: _scaffoldKey,
appBar: new AppBar(
title: new Text('Dialogs')
),
body: new Block(
padding: const EdgeInsets.symmetric(vertical: 24.0, horizontal: 72.0),
children: <Widget>[
new RaisedButton(
child: new Text('ALERT'),
onPressed: () {
showDemoDialog/*<DialogDemoAction>*/(
context: context,
dialog: new Dialog(
content: new Text(
_alertWithoutTitleText,
style: dialogTextStyle
),
actions: <Widget>[
new FlatButton(
child: new Text('CANCEL'),
onPressed: () { Navigator.pop(context, DialogDemoAction.cancel); }
),
new FlatButton(
child: new Text('DISCARD'),
onPressed: () { Navigator.pop(context, DialogDemoAction.discard); }
)
]
)
);
}
),
new RaisedButton(
child: new Text('ALERT WITH TITLE'),
onPressed: () {
showDemoDialog/*<DialogDemoAction>*/(
context: context,
dialog: new Dialog(
title: new Text('Use Google\'s location service?'),
content: new Text(
_alertWithTitleText,
style: dialogTextStyle
),
actions: <Widget>[
new FlatButton(
child: new Text('DISAGREE'),
onPressed: () { Navigator.pop(context, DialogDemoAction.disagree); }
),
new FlatButton(
child: new Text('AGREE'),
onPressed: () { Navigator.pop(context, DialogDemoAction.agree); }
)
]
)
);
}
),
new RaisedButton(
child: new Text('SIMPLE'),
onPressed: () {
showDemoDialog/*<String>*/(
context: context,
dialog: new Dialog(
title: new Text('Set backup account'),
content: new Column(
children: <Widget>[
new DialogDemoItem(
icon: Icons.account_circle,
color: theme.primaryColor,
text: 'username@gmail.com',
onPressed: () { Navigator.pop(context, 'username@gmail.com'); }
),
new DialogDemoItem(
icon: Icons.account_circle,
color: theme.primaryColor,
text: 'user02@gmail.com',
onPressed: () { Navigator.pop(context, 'user02@gmail.com'); }
),
new DialogDemoItem(
icon: Icons.add_circle,
text: 'add account',
color: theme.disabledColor
)
]
)
)
);
}
),
new RaisedButton(
child: new Text('CONFIRMATION'),
onPressed: () {
showTimePicker(
context: context,
initialTime: const TimeOfDay(hour: 15, minute: 30)
)
.then((TimeOfDay value) { // The value passed to Navigator.pop() or null.
if (value != null) {
_scaffoldKey.currentState.showSnackBar(new SnackBar(
content: new Text('You selected: $value')
));
}
});
}
),
new RaisedButton(
child: new Text('FULLSCREEN'),
onPressed: () {
Navigator.push(context, new MaterialPageRoute<DismissDialogAction>(
builder: (BuildContext context) => new FullScreenDialogDemo()
));
}
)
]
)
);
}
}
// 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 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_sprites/flutter_sprites.dart';
class DrawingDemo extends StatefulWidget {
static const String routeName = '/drawing';
@override
_DrawingDemoState createState() => new _DrawingDemoState();
}
class _DrawingDemoState extends State<DrawingDemo> {
_LineDrawingNode _rootNode;
ImageMap _images;
Future<Null> _loadAssets(AssetBundle bundle) async {
_images = new ImageMap(bundle);
await _images.load(<String>[
'packages/flutter_gallery_assets/fancylines.png'
]);
}
@override
void initState() {
super.initState();
_loadAssets(DefaultAssetBundle.of(context)).then((_) {
setState(() {
_rootNode = new _LineDrawingNode(_images);
});
});
}
@override
Widget build(BuildContext context) {
Widget body;
if (_rootNode == null) {
body = new Center(
child: new CircularProgressIndicator()
);
} else {
body = new SpriteWidget(_rootNode, SpriteBoxTransformMode.nativePoints);
}
return new Scaffold(
appBar: new AppBar(
title: new Text('Fancy lines')
),
body: body
);
}
}
class _LineDrawingNode extends NodeWithSize {
_LineDrawingNode(this._images) : super(const Size(1024.0, 1024.0)) {
userInteractionEnabled = true;
}
final ImageMap _images;
EffectLine _currentLine;
@override
bool handleEvent(SpriteBoxEvent event) {
if (event.type == PointerDownEvent) {
_currentLine = new EffectLine(
texture: new Texture(_images['packages/flutter_gallery_assets/fancylines.png']),
colorSequence: new ColorSequence.fromStartAndEndColor(Colors.purple[500], Colors.purple[600]),
fadeAfterDelay: 3.0,
fadeDuration: 1.0
);
_currentLine.addPoint(event.boxPosition);
addChild(_currentLine);
} else if (event.type == PointerMoveEvent) {
_currentLine.addPoint(event.boxPosition);
}
return true;
}
}
// Copyright 2015 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';
class DropDownDemo extends StatefulWidget {
static const String routeName = '/dropdown';
@override
_DropDownDemoState createState() => new _DropDownDemoState();
}
class _DropDownDemoState extends State<DropDownDemo> {
String _value = "Free";
List<DropDownMenuItem<String>> buildItems() {
return <String>["One", "Two", "Free", "Four"].map((String value) {
return new DropDownMenuItem<String>(value: value, child: new Text(value));
})
.toList();
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text('Drop-down button')),
body: new Center(
child: new DropDownButton<String>(
items: buildItems(),
value: _value,
onChanged: (String newValue) {
setState(() {
if (newValue != null)
_value = newValue;
});
}
)
)
);
}
}
// Copyright 2015 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';
class _ContactCategory extends StatelessWidget {
_ContactCategory({ Key key, this.icon, this.children }) : super(key: key);
final IconData icon;
final List<Widget> children;
@override
Widget build(BuildContext context) {
return new Container(
padding: const EdgeInsets.symmetric(vertical: 16.0),
decoration: new BoxDecoration(
border: new Border(bottom: new BorderSide(color: Theme.of(context).dividerColor))
),
child: new DefaultTextStyle(
style: Theme.of(context).textTheme.subhead,
child: new Row(
children: <Widget>[
new SizedBox(
width: 72.0,
child: new Icon(icon: icon, color: Theme.of(context).primaryColor)
),
new Flexible(child: new Column(children: children))
]
)
)
);
}
}
class _ContactItem extends StatelessWidget {
_ContactItem({ Key key, this.icon, this.lines }) : super(key: key) {
assert(lines.length > 1);
}
final IconData icon;
final List<String> lines;
@override
Widget build(BuildContext context) {
List<Widget> columnChildren = lines.sublist(0, lines.length - 1).map((String line) => new Text(line)).toList();
columnChildren.add(new Text(lines.last, style: Theme.of(context).textTheme.caption));
List<Widget> rowChildren = <Widget>[
new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: columnChildren
)
];
if (icon != null) {
rowChildren.add(new SizedBox(
width: 72.0,
child: new Icon(icon: icon, color: Theme.of(context).disabledColor)
));
}
return new Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: rowChildren
)
);
}
}
class FlexibleSpaceDemo extends StatefulWidget {
static const String routeName = '/flexible-space';
@override
FlexibleSpaceDemoState createState() => new FlexibleSpaceDemoState();
}
class FlexibleSpaceDemoState extends State<FlexibleSpaceDemo> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
final double _appBarHeight = 256.0;
AppBarBehavior _appBarBehavior = AppBarBehavior.scroll;
@override
Widget build(BuildContext context) {
final double statusBarHeight = MediaQuery.of(context).padding.top;
return new Theme(
data: new ThemeData(
brightness: ThemeBrightness.light,
primarySwatch: Colors.indigo
),
child: new Scaffold(
key: _scaffoldKey,
appBarBehavior: _appBarBehavior,
appBar: new AppBar(
expandedHeight: _appBarHeight,
actions: <Widget>[
new IconButton(
icon: Icons.create,
tooltip: 'Search',
onPressed: () {
_scaffoldKey.currentState.showSnackBar(new SnackBar(
content: new Text('Not supported.')
));
}
),
new PopupMenuButton<AppBarBehavior>(
onSelected: (AppBarBehavior value) {
setState(() {
_appBarBehavior = value;
});
},
itemBuilder: (BuildContext context) => <PopupMenuItem<AppBarBehavior>>[
new PopupMenuItem<AppBarBehavior>(
value: AppBarBehavior.scroll,
child: new Text('Toolbar scrolls away')
),
new PopupMenuItem<AppBarBehavior>(
value: AppBarBehavior.under,
child: new Text('Toolbar stays put')
)
]
)
],
flexibleSpace: new FlexibleSpaceBar(
title : new Text('Ali Connors'),
background: new AssetImage(
name: 'packages/flutter_gallery_assets/ali_connors.png',
fit: ImageFit.cover,
height: _appBarHeight
)
)
),
body: new Block(
padding: new EdgeInsets.only(top: _appBarHeight + statusBarHeight),
children: <Widget>[
new _ContactCategory(
icon: Icons.call,
children: <Widget>[
new _ContactItem(
icon: Icons.message,
lines: <String>[
'(650) 555-1234',
'Mobile'
]
),
new _ContactItem(
icon: Icons.message,
lines: <String>[
'(323) 555-6789',
'Work'
]
)
]
),
new _ContactCategory(
icon: Icons.email,
children: <Widget>[
new _ContactItem(
lines: <String>[
'ali_connors@example.com',
'Personal'
]
),
new _ContactItem(
lines: <String>[
'aliconnors@example.com',
'Work'
]
)
]
),
new _ContactCategory(
icon: Icons.location_on,
children: <Widget>[
new _ContactItem(
lines: <String>[
'2000 Main Street',
'San Francisco, CA',
'Home'
]
),
new _ContactItem(
lines: <String>[
'1600 Amphitheater Parkway',
'Mountain View, CA',
'Work'
]
),
new _ContactItem(
lines: <String>[
'126 Severyns Ave',
'Mountain View, CA',
'Jet Travel'
]
)
]
)
]
)
)
);
}
}
// 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:intl/intl.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
// This demo is based on
// https://www.google.com/design/spec/components/dialogs.html#dialogs-full-screen-dialogs
enum DismissDialogAction {
cancel,
discard,
save,
}
class DateTimeItem extends StatelessWidget {
DateTimeItem({ Key key, DateTime dateTime, this.onChanged })
: date = new DateTime(dateTime.year, dateTime.month, dateTime.day),
time = new TimeOfDay(hour: dateTime.hour, minute: dateTime.minute),
super(key: key) {
assert(onChanged != null);
}
final DateTime date;
final TimeOfDay time;
final ValueChanged<DateTime> onChanged;
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
return new DefaultTextStyle(
style: theme.textTheme.subhead,
child: new Row(
children: <Widget>[
new Flexible(
child: new Container(
padding: const EdgeInsets.symmetric(vertical: 8.0),
decoration: new BoxDecoration(
border: new Border(bottom: new BorderSide(color: theme.dividerColor))
),
child: new InkWell(
onTap: () {
showDatePicker(
context: context,
initialDate: date,
firstDate: date.subtract(const Duration(days: 30)),
lastDate: date.add(const Duration(days: 30))
)
.then((DateTime value) {
onChanged(new DateTime(value.year, value.month, value.day, time.hour, time.minute));
});
},
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Text(new DateFormat('EEE, MMM d yyyy').format(date)),
new Icon(icon: Icons.arrow_drop_down, color: Colors.black54),
]
)
)
)
),
new Container(
margin: const EdgeInsets.only(left: 8.0),
padding: const EdgeInsets.symmetric(vertical: 8.0),
decoration: new BoxDecoration(
border: new Border(bottom: new BorderSide(color: theme.dividerColor))
),
child: new InkWell(
onTap: () {
showTimePicker(
context: context,
initialTime: time
)
.then((TimeOfDay value) {
onChanged(new DateTime(date.year, date.month, date.day, value.hour, value.minute));
});
},
child: new Row(
children: <Widget>[
new Text('$time'),
new Icon(icon: Icons.arrow_drop_down, color: Colors.black54),
]
)
)
)
]
)
);
}
}
class FullScreenDialogDemo extends StatefulWidget {
@override
FullScreenDialogDemoState createState() => new FullScreenDialogDemoState();
}
class FullScreenDialogDemoState extends State<FullScreenDialogDemo> {
DateTime _fromDateTime = new DateTime.now();
DateTime _toDateTime = new DateTime.now();
bool _allDayValue = false;
bool _saveNeeded = false;
void handleDismissButton(BuildContext context) {
if (!_saveNeeded) {
Navigator.pop(context, null);
return;
}
final ThemeData theme = Theme.of(context);
final TextStyle dialogTextStyle = theme.textTheme.subhead.copyWith(color: theme.textTheme.caption.color);
showDialog(
context: context,
child: new Dialog(
content: new Text(
'Discard new event?',
style: dialogTextStyle
),
actions: <Widget>[
new FlatButton(
child: new Text('CANCEL'),
onPressed: () { Navigator.pop(context, DismissDialogAction.cancel); }
),
new FlatButton(
child: new Text('DISCARD'),
onPressed: () {
Navigator.openTransaction(context, (NavigatorTransaction transaction) {
transaction.pop(DismissDialogAction.discard); // pop the cancel/discard dialog
transaction.pop(null); // pop this route
});
}
)
]
)
);
}
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
return new Scaffold(
appBar: new AppBar(
leading: new IconButton(
icon: Icons.clear,
onPressed: () { handleDismissButton(context); }
),
title: new Text('New event'),
actions: <Widget> [
new FlatButton(
child: new Text('SAVE', style: theme.textTheme.body1.copyWith(color: Colors.white)),
onPressed: () {
Navigator.pop(context, DismissDialogAction.save);
}
)
]
),
body: new Block(
padding: const EdgeInsets.all(16.0),
children: <Widget>[
new Container(
padding: const EdgeInsets.symmetric(vertical: 8.0),
decoration: new BoxDecoration(
border: new Border(bottom: new BorderSide(color: theme.dividerColor))
),
child: new Align(
alignment: FractionalOffset.bottomLeft,
child: new Text('Event name', style: theme.textTheme.display2)
)
),
new Container(
padding: const EdgeInsets.symmetric(vertical: 8.0),
decoration: new BoxDecoration(
border: new Border(bottom: new BorderSide(color: theme.dividerColor))
),
child: new Align(
alignment: FractionalOffset.bottomLeft,
child: new Text('Location', style: theme.textTheme.title.copyWith(color: Colors.black54))
)
),
new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Text('From', style: theme.textTheme.caption),
new DateTimeItem(
dateTime: _fromDateTime,
onChanged: (DateTime value) {
setState(() {
_fromDateTime = value;
_saveNeeded = true;
});
}
)
]
),
new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Text('To', style: theme.textTheme.caption),
new DateTimeItem(
dateTime: _toDateTime,
onChanged: (DateTime value) {
setState(() {
_toDateTime = value;
_saveNeeded = true;
});
}
)
]
),
new Container(
decoration: new BoxDecoration(
border: new Border(bottom: new BorderSide(color: theme.dividerColor))
),
child: new Row(
children: <Widget> [
new Checkbox(
value: _allDayValue,
onChanged: (bool value) {
setState(() {
_allDayValue = value;
_saveNeeded = true;
});
}
),
new Text('All-day')
]
)
)
]
.map((Widget child) {
return new Container(
padding: const EdgeInsets.symmetric(vertical: 8.0),
height: 96.0,
child: child
);
})
.toList()
)
);
}
}
// 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 'dart:collection';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import '../gallery/demo.dart';
const String _kExampleCode = 'gridlists';
enum GridDemoTileStyle {
imageOnly,
oneLine,
twoLine
}
class Photo {
Photo({ this.assetName, this.title, this.caption, this.isFavorite: false });
final String assetName;
final String title;
final String caption;
bool isFavorite;
bool get isValid => assetName != null && title != null && caption != null && isFavorite != null;
}
const String photoHeroTag = 'Photo';
typedef void PhotoFavoriteCallback(Photo photo);
class GridDemoPhotoItem extends StatelessWidget {
GridDemoPhotoItem({
Key key,
this.photo,
this.tileStyle,
this.onPressedFavorite
}) : super(key: key) {
assert(photo != null && photo.isValid);
assert(tileStyle != null);
assert(onPressedFavorite != null);
}
final Photo photo;
final GridDemoTileStyle tileStyle;
final PhotoFavoriteCallback onPressedFavorite;
void showPhoto(BuildContext context) {
Key photoKey = new Key(photo.assetName);
Set<Key> mostValuableKeys = new HashSet<Key>();
mostValuableKeys.add(photoKey);
Navigator.push(context, new MaterialPageRoute<Null>(
settings: new RouteSettings(
mostValuableKeys: mostValuableKeys
),
builder: (BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(photo.title)
),
body: new Material(
child: new Hero(
tag: photoHeroTag,
child: new AssetImage(
name: photo.assetName,
fit: ImageFit.cover
)
)
)
);
}
));
}
@override
Widget build(BuildContext context) {
final Widget image = new GestureDetector(
onTap: () { showPhoto(context); },
child: new Hero(
key: new Key(photo.assetName),
tag: photoHeroTag,
child: new AssetImage(
name: photo.assetName,
fit: ImageFit.cover
)
)
);
IconData icon = photo.isFavorite ? Icons.star : Icons.star_border;
switch(tileStyle) {
case GridDemoTileStyle.imageOnly:
return image;
case GridDemoTileStyle.oneLine:
return new GridTile(
header: new GridTileBar(
backgroundColor: Colors.black45,
leading: new IconButton(
icon: icon,
color: Colors.white,
onPressed: () { onPressedFavorite(photo); }
),
title: new Text(photo.title)
),
child: image
);
case GridDemoTileStyle.twoLine:
return new GridTile(
footer: new GridTileBar(
backgroundColor: Colors.black45,
title: new Text(photo.title),
subtitle: new Text(photo.caption),
trailing: new IconButton(
icon: icon,
color: Colors.white,
onPressed: () { onPressedFavorite(photo); }
)
),
child: image
);
}
}
}
class GridListDemo extends StatefulWidget {
GridListDemo({ Key key }) : super(key: key);
static const String routeName = '/grid-list';
@override
GridListDemoState createState() => new GridListDemoState();
}
class GridListDemoState extends State<GridListDemo> {
GridDemoTileStyle tileStyle = GridDemoTileStyle.twoLine;
List<Photo> photos = <Photo>[
new Photo(
assetName: 'packages/flutter_gallery_assets/landscape_0.jpg',
title: 'Philippines',
caption: 'Batad rice terraces'
),
new Photo(
assetName: 'packages/flutter_gallery_assets/landscape_1.jpg',
title: 'Italy',
caption: 'Ceresole Reale'
),
new Photo(
assetName: 'packages/flutter_gallery_assets/landscape_2.jpg',
title: 'Somewhere',
caption: 'Beautiful mountains'
),
new Photo(
assetName: 'packages/flutter_gallery_assets/landscape_3.jpg',
title: 'A place',
caption: 'Beautiful hills'
),
new Photo(
assetName: 'packages/flutter_gallery_assets/landscape_4.jpg',
title: 'New Zealand',
caption: 'View from the van'
),
new Photo(
assetName: 'packages/flutter_gallery_assets/landscape_5.jpg',
title: 'Autumn',
caption: 'The golden season'
),
new Photo(
assetName: 'packages/flutter_gallery_assets/landscape_6.jpg',
title: 'Germany',
caption: 'Englischer Garten'
),
new Photo(
assetName: 'packages/flutter_gallery_assets/landscape_7.jpg',
title: 'A country',
caption: 'Grass fields'
),
new Photo(
assetName: 'packages/flutter_gallery_assets/landscape_8.jpg',
title: 'Mountain country',
caption: 'River forest'
),
new Photo(
assetName: 'packages/flutter_gallery_assets/landscape_9.jpg',
title: 'Alpine place',
caption: 'Green hills'
),
new Photo(
assetName: 'packages/flutter_gallery_assets/landscape_10.jpg',
title: 'Desert land',
caption: 'Blue skies'
),
new Photo(
assetName: 'packages/flutter_gallery_assets/landscape_11.jpg',
title: 'Narnia',
caption: 'Rocks and rivers'
),
];
void showTileStyleMenu(BuildContext context) {
final List<PopupMenuItem<GridDemoTileStyle>> items = <PopupMenuItem<GridDemoTileStyle>>[
new PopupMenuItem<GridDemoTileStyle>(
value: GridDemoTileStyle.imageOnly,
child: new Text('Image only')
),
new PopupMenuItem<GridDemoTileStyle>(
value: GridDemoTileStyle.oneLine,
child: new Text('One line')
),
new PopupMenuItem<GridDemoTileStyle>(
value: GridDemoTileStyle.twoLine,
child: new Text('Two line')
)
];
final EdgeInsets padding = MediaQuery.of(context).padding;
final RelativeRect position = new RelativeRect.fromLTRB(
0.0, padding.top + 16.0, padding.right + 16.0, 0.0
);
showMenu(context: context, position: position, items: items).then((GridDemoTileStyle value) {
setState(() {
tileStyle = value;
});
});
}
// When the ScrollableGrid first appears we want the last row to only be
// partially visible, to help the user recognize that the grid is scrollable.
// The GridListDemoGridDelegate's tileHeightFactor is used for this.
@override
Widget build(BuildContext context) {
final Orientation orientation = MediaQuery.of(context).orientation;
return new Scaffold(
appBar: new AppBar(
title: new Text('Grid list'),
actions: <Widget>[
new IconButton(
icon: Icons.more_vert,
onPressed: () { showTileStyleMenu(context); },
tooltip: 'Show menu'
)
]
),
body: new Column(
children: <Widget>[
new Flexible(
child: new ScrollableGrid(
delegate: new FixedColumnCountGridDelegate(
columnCount: (orientation == Orientation.portrait) ? 2 : 3,
rowSpacing: 4.0,
columnSpacing: 4.0,
padding: const EdgeInsets.all(4.0),
tileAspectRatio: (orientation == Orientation.portrait) ? 1.0 : 1.3
),
children: photos.map((Photo photo) {
return new GridDemoPhotoItem(
photo: photo,
tileStyle: tileStyle,
onPressedFavorite: (Photo photo) {
setState(() {
photo.isFavorite = !photo.isFavorite;
});
}
);
})
)
),
new DemoBottomBar(
exampleCodeTag: _kExampleCode
)
]
)
);
}
}
// 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';
class IconsDemo extends StatefulWidget {
static const String routeName = '/icons';
@override
IconsDemoState createState() => new IconsDemoState();
}
class IconsDemoState extends State<IconsDemo> {
static final List<Map<int, Color>> iconColorSwatches = <Map<int, Color>>[
Colors.red,
Colors.pink,
Colors.purple,
Colors.deepPurple,
Colors.indigo,
Colors.blue,
Colors.lightBlue,
Colors.cyan,
Colors.teal,
Colors.green,
Colors.lightGreen,
Colors.lime,
Colors.yellow,
Colors.amber,
Colors.orange,
Colors.deepOrange,
Colors.brown,
Colors.grey,
Colors.blueGrey
];
int iconColorIndex = 2;
double iconOpacity = 1.0;
Color get iconColor => iconColorSwatches[iconColorIndex][400];
void handleIconButtonPress() {
setState(() {
iconColorIndex = (iconColorIndex + 1) % iconColorSwatches.length;
});
}
Widget buildIconButton(double size, IconData icon, bool enabled) {
return new IconButton(
size: size,
icon: icon,
color: iconColor,
tooltip: "${enabled ? 'enabled' : 'disabled'} icon button",
onPressed: enabled ? handleIconButtonPress : null
);
}
Widget buildSizeLabel(int size, TextStyle style) {
return new SizedBox(
height: size.toDouble() + 16.0, // to match an IconButton's padded height
child: new Center(
child: new Text('$size', style: style)
)
);
}
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final TextStyle textStyle = theme.textTheme.subhead.copyWith(color: theme.textTheme.caption.color);
return new Scaffold(
appBar: new AppBar(
title: new Text('Icons')
),
body: new IconTheme(
data: new IconThemeData(opacity: iconOpacity),
child: new Padding(
padding: const EdgeInsets.all(24.0),
child: new Column(
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Flexible(
flex: 0,
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Text('Size', style: textStyle),
buildSizeLabel(18, textStyle),
buildSizeLabel(24, textStyle),
buildSizeLabel(36, textStyle),
buildSizeLabel(48, textStyle)
]
)
),
new Flexible(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Text('Enabled', style: textStyle),
buildIconButton(18.0, Icons.face, true),
buildIconButton(24.0, Icons.alarm, true),
buildIconButton(36.0, Icons.home, true),
buildIconButton(48.0, Icons.android, true)
]
)
),
new Flexible(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Text('Disabled', style: textStyle),
buildIconButton(18.0, Icons.face, false),
buildIconButton(24.0, Icons.alarm, false),
buildIconButton(36.0, Icons.home, false),
buildIconButton(48.0, Icons.android, false)
]
)
)
]
),
new Flexible(
child: new Center(
child: new IconTheme(
data: new IconThemeData(opacity: 1.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Icon(
icon: Icons.brightness_7,
color: iconColor.withAlpha(0x33) // 0.2 * 255 = 0x33
),
new Slider(
value: iconOpacity,
min: 0.2,
max: 1.0,
activeColor: iconColor,
onChanged: (double newValue) {
setState(() {
iconOpacity = newValue;
});
}
),
new Icon(
icon: Icons.brightness_7,
color: iconColor.withAlpha(0xFF)
),
]
)
)
)
)
]
)
)
)
);
}
}
// 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:collection/collection.dart' show lowerBound;
import 'package:flutter/material.dart';
enum LeaveBehindDemoAction {
reset,
horizontalSwipe,
leftSwipe,
rightSwipe
}
class LeaveBehindItem implements Comparable<LeaveBehindItem> {
LeaveBehindItem({ this.index, this.name, this.subject, this.body });
LeaveBehindItem.from(LeaveBehindItem item)
: index = item.index, name = item.name, subject = item.subject, body = item.body;
final int index;
final String name;
final String subject;
final String body;
@override
int compareTo(LeaveBehindItem other) => index.compareTo(other.index);
}
class LeaveBehindDemo extends StatefulWidget {
LeaveBehindDemo({ Key key }) : super(key: key);
static const String routeName = '/leave-behind';
@override
LeaveBehindDemoState createState() => new LeaveBehindDemoState();
}
class LeaveBehindDemoState extends State<LeaveBehindDemo> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
DismissDirection _dismissDirection = DismissDirection.horizontal;
List<LeaveBehindItem> leaveBehindItems;
void initListItems() {
leaveBehindItems = new List<LeaveBehindItem>.generate(16, (int index) {
return new LeaveBehindItem(
index: index,
name: 'Item $index Sender',
subject: 'Subject: $index',
body: "[$index] first line of the message's body..."
);
});
}
@override
void initState() {
super.initState();
initListItems();
}
void handleDemoAction(LeaveBehindDemoAction action) {
switch(action) {
case LeaveBehindDemoAction.reset:
initListItems();
break;
case LeaveBehindDemoAction.horizontalSwipe:
_dismissDirection = DismissDirection.horizontal;
break;
case LeaveBehindDemoAction.leftSwipe:
_dismissDirection = DismissDirection.endToStart;
break;
case LeaveBehindDemoAction.rightSwipe:
_dismissDirection = DismissDirection.startToEnd;
break;
}
}
void handleUndo(LeaveBehindItem item) {
int insertionIndex = lowerBound(leaveBehindItems, item);
setState(() {
leaveBehindItems.insert(insertionIndex, item);
});
}
Widget buildItem(LeaveBehindItem item) {
final ThemeData theme = Theme.of(context);
return new Dismissable(
key: new ObjectKey(item),
direction: _dismissDirection,
onDismissed: (DismissDirection direction) {
setState(() {
leaveBehindItems.remove(item);
});
final String action = (direction == DismissDirection.endToStart) ? 'archived' : 'deleted';
_scaffoldKey.currentState.showSnackBar(new SnackBar(
content: new Text('You $action item ${item.index}'),
action: new SnackBarAction(
label: 'UNDO',
onPressed: () { handleUndo(item); }
)
));
},
background: new Container(
decoration: new BoxDecoration(backgroundColor: theme.primaryColor),
child: new ListItem(
leading: new Icon(icon: Icons.delete, color: Colors.white, size: 36.0)
)
),
secondaryBackground: new Container(
decoration: new BoxDecoration(backgroundColor: theme.primaryColor),
child: new ListItem(
trailing: new Icon(icon: Icons.archive, color: Colors.white, size: 36.0)
)
),
child: new Container(
decoration: new BoxDecoration(
backgroundColor: theme.canvasColor,
border: new Border(bottom: new BorderSide(color: theme.dividerColor))
),
child: new ListItem(
title: new Text(item.name),
subtitle: new Text('${item.subject}\n${item.body}'),
isThreeLine: true
)
)
);
}
@override
Widget build(BuildContext context) {
return new Scaffold(
key: _scaffoldKey,
appBar: new AppBar(
title: new Text('Swipe items to dismiss'),
actions: <Widget>[
new PopupMenuButton<LeaveBehindDemoAction>(
onSelected: handleDemoAction,
itemBuilder: (BuildContext context) => <PopupMenuEntry<LeaveBehindDemoAction>>[
new PopupMenuItem<LeaveBehindDemoAction>(
value: LeaveBehindDemoAction.reset,
child: new Text('Reset the list')
),
new PopupMenuDivider(),
new CheckedPopupMenuItem<LeaveBehindDemoAction>(
value: LeaveBehindDemoAction.horizontalSwipe,
checked: _dismissDirection == DismissDirection.horizontal,
child: new Text('Hoizontal swipe')
),
new CheckedPopupMenuItem<LeaveBehindDemoAction>(
value: LeaveBehindDemoAction.leftSwipe,
checked: _dismissDirection == DismissDirection.endToStart,
child: new Text('Only swipe left')
),
new CheckedPopupMenuItem<LeaveBehindDemoAction>(
value: LeaveBehindDemoAction.rightSwipe,
checked: _dismissDirection == DismissDirection.startToEnd,
child: new Text('Only swipe right')
)
]
)
]
),
body: new Block(
padding: new EdgeInsets.all(4.0),
children: leaveBehindItems.map(buildItem).toList()
)
);
}
}
// 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';
class ListDemo extends StatefulWidget {
ListDemo({ Key key }) : super(key: key);
static const String routeName = '/list';
@override
ListDemoState createState() => new ListDemoState();
}
class ListDemoState extends State<ListDemo> {
final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
PersistentBottomSheetController<Null> _bottomSheet;
MaterialListType _itemType = MaterialListType.threeLine;
bool _dense = false;
bool _showAvatars = true;
bool _showIcons = false;
bool _showDividers = false;
bool _reverseSort = false;
List<String> items = <String>[
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N'
];
void changeItemType(MaterialListType type) {
setState(() {
_itemType = type;
});
_bottomSheet?.setState(() { });
}
void showConfigurationSheet(BuildContext appContext) {
_bottomSheet = scaffoldKey.currentState.showBottomSheet((BuildContext bottomSheetContext) {
return new Container(
decoration: new BoxDecoration(
border: new Border(top: new BorderSide(color: Colors.black26))
),
child: new Block(
children: <Widget>[
new ListItem(
dense: true,
title: new Text('One-line'),
trailing: new Radio<MaterialListType>(
value: _showAvatars ? MaterialListType.oneLineWithAvatar : MaterialListType.oneLine,
groupValue: _itemType,
onChanged: changeItemType
)
),
new ListItem(
dense: true,
title: new Text('Two-line'),
trailing: new Radio<MaterialListType>(
value: MaterialListType.twoLine,
groupValue: _itemType,
onChanged: changeItemType
)
),
new ListItem(
dense: true,
title: new Text('Three-line'),
trailing: new Radio<MaterialListType>(
value: MaterialListType.threeLine,
groupValue: _itemType,
onChanged: changeItemType
)
),
new ListItem(
dense: true,
title: new Text('Show avatar'),
trailing: new Checkbox(
value: _showAvatars,
onChanged: (bool value) {
setState(() {
_showAvatars = value;
});
_bottomSheet?.setState(() { });
}
)
),
new ListItem(
dense: true,
title: new Text('Show icon'),
trailing: new Checkbox(
value: _showIcons,
onChanged: (bool value) {
setState(() {
_showIcons = value;
});
_bottomSheet?.setState(() { });
}
)
),
new ListItem(
dense: true,
title: new Text('Show dividers'),
trailing: new Checkbox(
value: _showDividers,
onChanged: (bool value) {
setState(() {
_showDividers = value;
});
_bottomSheet?.setState(() { });
}
)
),
new ListItem(
dense: true,
title: new Text('Dense layout'),
trailing: new Checkbox(
value: _dense,
onChanged: (bool value) {
setState(() {
_dense = value;
});
_bottomSheet?.setState(() { });
}
)
)
]
)
);
});
}
Widget buildListItem(BuildContext context, String item) {
Widget secondary;
if (_itemType == MaterialListType.twoLine) {
secondary = new Text(
"Additional item information."
);
} else if (_itemType == MaterialListType.threeLine) {
secondary = new Text(
"Even more additional list item information appears on line three."
);
}
return new ListItem(
isThreeLine: _itemType == MaterialListType.threeLine,
dense: _dense,
leading: _showAvatars ? new CircleAvatar(child: new Text(item)) : null,
title: new Text('This item represents $item.'),
subtitle: secondary,
trailing: _showIcons ? new Icon(icon: Icons.info, color: Theme.of(context).disabledColor) : null
);
}
@override
Widget build(BuildContext context) {
final String layoutText = _dense ? " \u2013 Dense" : "";
String itemTypeText;
switch(_itemType) {
case MaterialListType.oneLine:
case MaterialListType.oneLineWithAvatar:
itemTypeText = 'Single-line';
break;
case MaterialListType.twoLine:
itemTypeText = 'Two-line';
break;
case MaterialListType.threeLine:
itemTypeText = 'Three-line';
break;
}
Iterable<Widget> listItems = items.map((String item) => buildListItem(context, item));
if (_showDividers)
listItems = ListItem.divideItems(context: context, items: listItems);
return new Scaffold(
key: scaffoldKey,
appBar: new AppBar(
title: new Text('Scrolling list\n$itemTypeText$layoutText'),
actions: <Widget>[
new IconButton(
icon: Icons.sort_by_alpha,
tooltip: 'Sort',
onPressed: () {
setState(() {
_reverseSort = !_reverseSort;
items.sort((String a, String b) => _reverseSort ? b.compareTo(a) : a.compareTo(b));
});
}
),
new IconButton(
icon: Icons.more_vert,
tooltip: 'Show menu',
onPressed: () { showConfigurationSheet(context); }
)
]
),
body: new OverscrollIndicator(
child: new Scrollbar(
child: new MaterialList(
type: _itemType,
padding: new EdgeInsets.symmetric(vertical: _dense ? 4.0 : 8.0),
children: listItems
)
)
)
);
}
}
// 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';
class MenuDemo extends StatefulWidget {
MenuDemo({ Key key }) : super(key: key);
static const String routeName = '/menu';
@override
MenuDemoState createState() => new MenuDemoState();
}
class MenuDemoState extends State<MenuDemo> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
final String _simpleValue1 = 'Menu item value one';
final String _simpleValue2 = 'Menu item value two';
final String _simpleValue3 = 'Menu item value three';
String _simpleValue;
final String _checkedValue1 = 'One';
final String _checkedValue2 = 'Two';
final String _checkedValue3 = 'Free';
final String _checkedValue4 = 'Four';
List<String> _checkedValues;
@override
void initState() {
super.initState();
_simpleValue = _simpleValue2;
_checkedValues = <String>[_checkedValue3];
}
void showInSnackBar(String value) {
_scaffoldKey.currentState.showSnackBar(new SnackBar(
content: new Text(value)
));
}
void showMenuSelection(String value) {
if (<String>[_simpleValue1, _simpleValue2, _simpleValue3].contains(value))
_simpleValue = value;
showInSnackBar('You selected: $value');
}
void showCheckedMenuSelections(String value) {
if (_checkedValues.contains(value))
_checkedValues.remove(value);
else
_checkedValues.add(value);
showInSnackBar('Checked $_checkedValues');
}
bool isChecked(String value) => _checkedValues.contains(value);
@override
Widget build(BuildContext context) {
return new Scaffold(
key: _scaffoldKey,
appBar: new AppBar(
title: new Text('Menus'),
actions: <Widget>[
new PopupMenuButton<String>(
onSelected: showMenuSelection,
itemBuilder: (BuildContext context) => <PopupMenuItem<String>>[
new PopupMenuItem<String>(
value: 'Toolbar menu',
child: new Text('Toolbar menu')
),
new PopupMenuItem<String>(
value: 'Right here',
child: new Text('Right here')
),
new PopupMenuItem<String>(
value: 'Hooray!',
child: new Text('Hooray!')
),
]
)
]
),
body: new Block(
padding: const EdgeInsets.symmetric(vertical: 8.0),
children: <Widget>[
// Pressing the PopupMenuButton on the right of this item shows
// a simple menu with one disabled item. Typically the contents
// of this "contextual menu" would reflect the app's state.
new ListItem(
title: new Text('An item with a context menu button'),
trailing: new PopupMenuButton<String>(
padding: EdgeInsets.zero,
onSelected: showMenuSelection,
itemBuilder: (BuildContext context) => <PopupMenuItem<String>>[
new PopupMenuItem<String>(
value: _simpleValue1,
child: new Text('Context menu item one')
),
new PopupMenuItem<String>(
enabled: false,
child: new Text('A disabled menu item')
),
new PopupMenuItem<String>(
value: _simpleValue3,
child: new Text('Context menu item three')
),
]
)
),
// Pressing the PopupMenuButton on the right of this item shows
// a menu whose items have text labels and icons and a divider
// That separates the first three items from the last one.
new ListItem(
title: new Text('An item with a sectioned menu'),
trailing: new PopupMenuButton<String>(
padding: EdgeInsets.zero,
onSelected: showMenuSelection,
itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
new PopupMenuItem<String>(
value: 'Preview',
child: new ListItem(
leading: new Icon(icon: Icons.visibility),
title: new Text('Preview')
)
),
new PopupMenuItem<String>(
value: 'Share',
child: new ListItem(
leading: new Icon(icon: Icons.person_add),
title: new Text('Share')
)
),
new PopupMenuItem<String>(
value: 'Get Link',
child: new ListItem(
leading: new Icon(icon: Icons.link),
title: new Text('Get link')
)
),
new PopupMenuDivider(),
new PopupMenuItem<String>(
value: 'Remove',
child: new ListItem(
leading: new Icon(icon: Icons.delete),
title: new Text('Remove')
)
)
]
)
),
// This entire list item is a PopupMenuButton. Tapping anywhere shows
// a menu whose current value is highlighted and aligned over the
// list item's center line.
new PopupMenuButton<String>(
padding: EdgeInsets.zero,
initialValue: _simpleValue,
onSelected: showMenuSelection,
child: new ListItem(
title: new Text('An item with a simple menu'),
subtitle: new Text(_simpleValue)
),
itemBuilder: (BuildContext context) => <PopupMenuItem<String>>[
new PopupMenuItem<String>(
value: _simpleValue1,
child: new Text(_simpleValue1)
),
new PopupMenuItem<String>(
value: _simpleValue2,
child: new Text(_simpleValue2)
),
new PopupMenuItem<String>(
value: _simpleValue3,
child: new Text(_simpleValue3)
)
]
),
// Pressing the PopupMenuButton on the right of this item shows a menu
// whose items have checked icons that reflect this app's state.
new ListItem(
title: new Text('An item with a checklist menu'),
trailing: new PopupMenuButton<String>(
padding: EdgeInsets.zero,
onSelected: showCheckedMenuSelections,
itemBuilder: (BuildContext context) => <PopupMenuItem<String>>[
new CheckedPopupMenuItem<String>(
value: _checkedValue1,
checked: isChecked(_checkedValue1),
child: new Text(_checkedValue1)
),
new CheckedPopupMenuItem<String>(
value: _checkedValue2,
enabled: false,
checked: isChecked(_checkedValue2),
child: new Text(_checkedValue2)
),
new CheckedPopupMenuItem<String>(
value: _checkedValue3,
checked: isChecked(_checkedValue3),
child: new Text(_checkedValue3)
),
new CheckedPopupMenuItem<String>(
value: _checkedValue4,
checked: isChecked(_checkedValue4),
child: new Text(_checkedValue4)
)
]
)
)
]
)
);
}
}
// Copyright 2015 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';
final TextStyle _kTextStyle = new TextStyle(
color: Colors.indigo[400],
fontSize: 24.0
);
class ModalBottomSheetDemo extends StatelessWidget {
static const String routeName = '/modal-bottom-sheet';
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text('Modal bottom sheet')),
body: new Center(
child: new RaisedButton(
child: new Text('SHOW BOTTOM SHEET'),
onPressed: () {
showModalBottomSheet/*<Null>*/(context: context, builder: (BuildContext context) {
return new Container(
child: new Padding(
padding: const EdgeInsets.all(32.0),
child: new Text('This is the modal bottom sheet. Click anywhere to dismiss.',
style: _kTextStyle,
textAlign: TextAlign.center
)
)
);
});
}
)
)
);
}
}
// 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 'dart:async';
import 'package:flutter/material.dart';
enum IndicatorType { overscroll, refresh }
class OverscrollDemo extends StatefulWidget {
OverscrollDemo({ Key key }) : super(key: key);
static const String routeName = '/overscroll';
@override
OverscrollDemoState createState() => new OverscrollDemoState();
}
class OverscrollDemoState extends State<OverscrollDemo> {
static final List<String> _items = <String>[
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N'
];
IndicatorType _type = IndicatorType.refresh;
Future<Null> refresh() {
Completer<Null> completer = new Completer<Null>();
new Timer(new Duration(seconds: 3), () { completer.complete(null); });
return completer.future;
}
@override
Widget build(BuildContext context) {
String indicatorTypeText;
switch(_type) {
case IndicatorType.overscroll:
indicatorTypeText = 'Over-scroll indicator';
break;
case IndicatorType.refresh:
indicatorTypeText = 'Refresh indicator';
break;
}
Widget body = new MaterialList(
type: MaterialListType.threeLine,
padding: const EdgeInsets.all(8.0),
children: _items.map((String item) {
return new ListItem(
isThreeLine: true,
leading: new CircleAvatar(child: new Text(item)),
title: new Text('This item represents $item.'),
subtitle: new Text('Even more additional list item information appears on line three.')
);
})
);
switch(_type) {
case IndicatorType.overscroll:
body = new OverscrollIndicator(child: body);
break;
case IndicatorType.refresh:
body = new RefreshIndicator(child: body, refresh: refresh);
break;
}
return new Scaffold(
appBar: new AppBar(
title: new Text('$indicatorTypeText'),
actions: <Widget>[
new IconButton(
icon: Icons.refresh,
tooltip: 'Pull to refresh',
onPressed: () {
setState(() {
_type = IndicatorType.refresh;
});
}
),
new IconButton(
icon: Icons.play_for_work,
tooltip: 'Over-scroll indicator',
onPressed: () {
setState(() {
_type = IndicatorType.overscroll;
});
}
)
]
),
body: body
);
}
}
// Copyright 2015 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';
class PageSelectorDemo extends StatelessWidget {
static const String routeName = '/page-selector';
void _handleArrowButtonPress(BuildContext context, int delta) {
final TabBarSelectionState<IconData> selection = TabBarSelection.of/*<IconData>*/(context);
if (!selection.valueIsChanging)
selection.value = selection.values[(selection.index + delta).clamp(0, selection.values.length - 1)];
}
@override
Widget build(BuildContext notUsed) { // Can't find the TabBarSelection from this context.
final List<IconData> icons = <IconData>[
Icons.event,
Icons.home,
Icons.android,
Icons.alarm,
Icons.face,
Icons.language,
];
return new Scaffold(
appBar: new AppBar(title: new Text('Page selector')),
body: new TabBarSelection<IconData>(
values: icons,
child: new Builder(
builder: (BuildContext context) {
final Color color = Theme.of(context).accentColor;
return new Column(
children: <Widget>[
new Container(
margin: const EdgeInsets.only(top: 16.0),
child: new Row(
children: <Widget>[
new IconButton(
icon: Icons.arrow_back,
color: color,
onPressed: () { _handleArrowButtonPress(context, -1); },
tooltip: 'Page back'
),
new TabPageSelector<IconData>(),
new IconButton(
icon: Icons.arrow_forward,
color: color,
onPressed: () { _handleArrowButtonPress(context, 1); },
tooltip: 'Page forward'
)
],
mainAxisAlignment: MainAxisAlignment.spaceBetween
)
),
new Flexible(
child: new TabBarView<IconData>(
children: icons.map((IconData icon) {
return new Container(
key: new ObjectKey(icon),
padding: const EdgeInsets.all(12.0),
child: new Card(
child: new Center(
child: new Icon(icon: icon, size: 128.0, color: color)
)
)
);
})
.toList()
)
)
]
);
}
)
)
);
}
}
// Copyright 2015 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';
final TextStyle _kTextStyle = new TextStyle(
color: Colors.indigo[400],
fontSize: 24.0
);
class PersistentBottomSheetDemo extends StatefulWidget {
static const String routeName = '/persistent-bottom-sheet';
@override
_PersistentBottomSheetDemoState createState() => new _PersistentBottomSheetDemoState();
}
class _PersistentBottomSheetDemoState extends State<PersistentBottomSheetDemo> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
VoidCallback _showBottomSheetCallback;
@override
void initState() {
super.initState();
_showBottomSheetCallback = showBottomSheet;
}
void showBottomSheet() {
setState(() { // disable the button
_showBottomSheetCallback = null;
});
_scaffoldKey.currentState.showBottomSheet/*<Null>*/((BuildContext context) {
return new Container(
decoration: new BoxDecoration(
border: new Border(top: new BorderSide(color: Colors.black26))
),
child: new Padding(
padding: const EdgeInsets.all(32.0),
child: new Text('This is a Material persistent bottom sheet. Drag downwards to dismiss it.',
style: _kTextStyle,
textAlign: TextAlign.center
)
)
);
})
.closed.then((_) {
setState(() { // re-enable the button
_showBottomSheetCallback = showBottomSheet;
});
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
key: _scaffoldKey,
appBar: new AppBar(title: new Text('Persistent bottom sheet')),
floatingActionButton: new FloatingActionButton(
child: new Icon(icon: Icons.add),
backgroundColor: Colors.redAccent[200]
),
body: new Center(
child: new RaisedButton(
onPressed: _showBottomSheetCallback,
child: new Text('SHOW BOTTOM SHEET')
)
)
);
}
}
// Copyright 2015 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';
class ProgressIndicatorDemo extends StatefulWidget {
static const String routeName = '/progress-indicator';
@override
_ProgressIndicatorDemoState createState() => new _ProgressIndicatorDemoState();
}
class _ProgressIndicatorDemoState extends State<ProgressIndicatorDemo> {
AnimationController _controller;
Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = new AnimationController(
duration: const Duration(milliseconds: 1500)
)..forward();
_animation = new CurvedAnimation(
parent: _controller,
curve: new Interval(0.0, 0.9, curve: Curves.ease),
reverseCurve: Curves.ease
)..addStatusListener((AnimationStatus status) {
if (status == AnimationStatus.dismissed)
_controller.forward();
else if (status == AnimationStatus.completed)
_controller.reverse();
});
}
@override
void dispose() {
_controller.stop();
super.dispose();
}
void _handleTap() {
setState(() {
// valueAnimation.isAnimating is part of our build state
if (_controller.isAnimating) {
_controller.stop();
} else {
switch (_controller.status) {
case AnimationStatus.dismissed:
case AnimationStatus.forward:
_controller.forward();
break;
case AnimationStatus.reverse:
case AnimationStatus.completed:
_controller.reverse();
break;
}
}
});
}
Widget _buildIndicators(BuildContext context, Widget child) {
List<Widget> indicators = <Widget>[
new SizedBox(
width: 200.0,
child: new LinearProgressIndicator()
),
new LinearProgressIndicator(),
new LinearProgressIndicator(),
new LinearProgressIndicator(value: _animation.value),
new CircularProgressIndicator(),
new SizedBox(
width: 20.0,
height: 20.0,
child: new CircularProgressIndicator(value: _animation.value)
),
new SizedBox(
width: 50.0,
height: 30.0,
child: new CircularProgressIndicator(value: _animation.value)
),
new Text('${(_animation.value * 100.0).toStringAsFixed(1)}%${ _controller.isAnimating ? "" : " (paused)" }')
];
return new Column(
children: indicators
.map((Widget c) => new Container(child: c, margin: const EdgeInsets.symmetric(vertical: 15.0, horizontal: 20.0)))
.toList(),
mainAxisAlignment: MainAxisAlignment.center
);
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text('Progress indicators')),
body: new DefaultTextStyle(
style: Theme.of(context).textTheme.title,
child: new GestureDetector(
onTap: _handleTap,
behavior: HitTestBehavior.opaque,
child: new Container(
padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 8.0),
child: new AnimatedBuilder(
animation: _animation,
builder: _buildIndicators
)
)
)
)
);
}
}
// Copyright 2015 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';
enum TabsDemoStyle {
iconsAndText,
iconsOnly,
textOnly
}
class ScrollableTabsDemo extends StatefulWidget {
static const String routeName = '/scrollable-tabs';
@override
ScrollableTabsDemoState createState() => new ScrollableTabsDemoState();
}
class ScrollableTabsDemoState extends State<ScrollableTabsDemo> {
final List<IconData> icons = <IconData>[
Icons.event,
Icons.home,
Icons.android,
Icons.alarm,
Icons.face,
Icons.language,
];
final Map<IconData, String> labels = <IconData, String>{
Icons.event: 'EVENT',
Icons.home: 'HOME',
Icons.android: 'ANDROID',
Icons.alarm: 'ALARM',
Icons.face: 'FACE',
Icons.language: 'LANGUAGE',
};
TabsDemoStyle _demoStyle = TabsDemoStyle.iconsAndText;
void changeDemoStyle(TabsDemoStyle style) {
setState(() {
_demoStyle = style;
});
}
@override
Widget build(BuildContext context) {
final Color iconColor = Theme.of(context).accentColor;
return new TabBarSelection<IconData>(
values: icons,
child: new Scaffold(
appBar: new AppBar(
title: new Text('Scrollable tabs'),
actions: <Widget>[
new PopupMenuButton<TabsDemoStyle>(
onSelected: changeDemoStyle,
itemBuilder: (BuildContext context) => <PopupMenuItem<TabsDemoStyle>>[
new PopupMenuItem<TabsDemoStyle>(
value: TabsDemoStyle.iconsAndText,
child: new Text('Icons and text')
),
new PopupMenuItem<TabsDemoStyle>(
value: TabsDemoStyle.iconsOnly,
child: new Text('Icons only')
),
new PopupMenuItem<TabsDemoStyle>(
value: TabsDemoStyle.textOnly,
child: new Text('Text only')
),
]
)
],
tabBar: new TabBar<IconData>(
isScrollable: true,
labels: new Map<IconData, TabLabel>.fromIterable(
icons,
value: (IconData icon) {
switch(_demoStyle) {
case TabsDemoStyle.iconsAndText:
return new TabLabel(text: labels[icon], icon: icon);
case TabsDemoStyle.iconsOnly:
return new TabLabel(icon: icon);
case TabsDemoStyle.textOnly:
return new TabLabel(text: labels[icon]);
}
}
)
)
),
body: new TabBarView<IconData>(
children: icons.map((IconData icon) {
return new Container(
key: new ObjectKey(icon),
padding: const EdgeInsets.all(12.0),
child:new Card(
child: new Center(
child: new Icon(
icon: icon,
color: iconColor,
size: 128.0
)
)
)
);
}).toList()
)
)
);
}
}
// 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 'flexible_space_demo.dart';
class _BarGraphic extends StatelessWidget {
_BarGraphic({ Key key, this.height, this.color, this.leftText, this.rightText: '' })
: super(key: key) {
assert(height != null);
assert(color != null);
assert(leftText != null);
}
final double height;
final Color color;
final String leftText;
final String rightText;
@override
Widget build(BuildContext context) {
return new Container(
height: height,
width: 200.0,
padding: const EdgeInsets.symmetric(horizontal: 16.0),
decoration: new BoxDecoration(backgroundColor: color),
child: new DefaultTextStyle(
style: Theme.of(context).textTheme.body1.copyWith(color: Colors.white),
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Text(leftText),
new Text(rightText)
]
)
)
);
}
}
class _StatusBarGraphic extends _BarGraphic {
_StatusBarGraphic() : super(
height: 24.0,
color: Colors.green[400],
leftText: 'Status Bar',
rightText: '24dp'
);
}
class _AppBarGraphic extends _BarGraphic {
_AppBarGraphic() : super(
height: 48.0,
color: Colors.blue[400],
leftText: 'Tool Bar',
rightText: '48dp'
);
}
class _TabBarGraphic extends _BarGraphic {
_TabBarGraphic() : super(
height: 48.0,
color: Colors.purple[400],
leftText: 'Tab Bar',
rightText: '56dp'
);
}
class _FlexibleSpaceGraphic extends _BarGraphic {
_FlexibleSpaceGraphic() : super(
height: 128.0,
color: Colors.pink[400],
leftText: 'Flexible Space'
);
}
class _TechniqueItem extends StatelessWidget {
_TechniqueItem({ this.titleText, this.barGraphics, this.builder });
final String titleText;
final List<Widget> barGraphics;
final WidgetBuilder builder;
void showDemo(BuildContext context) {
Navigator.push(context, new MaterialPageRoute<Null>(builder: builder));
}
@override
Widget build(BuildContext context) {
return new Card(
child: new InkWell(
onTap: () { showDemo(context); },
child: new Padding(
padding: const EdgeInsets.all(16.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children :<Widget>[
new Text(titleText),
new Column(children: barGraphics)
]
)
)
)
);
}
}
const String _introText =
"An AppBar is a combination of a ToolBar and a TabBar or a flexible space "
"Widget that is managed by the Scaffold. The Scaffold pads the ToolBar so that "
"it appears behind the device's status bar. When a flexible space Widget is "
"specified it is stacked on top of the ToolBar.";
class ScrollingTechniquesDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text('Scrolling techniques')),
body: new Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: new Block(
children: <Widget>[
new Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 32.0),
child: new Text(_introText, style: Theme.of(context).textTheme.caption)
),
new _TechniqueItem(
builder: (BuildContext context) => new FlexibleSpaceDemo(),
titleText: 'Standard',
barGraphics: <Widget>[
new _StatusBarGraphic(),
new _AppBarGraphic()
]
),
new _TechniqueItem(
titleText: 'Tabs',
builder: (BuildContext context) => new FlexibleSpaceDemo(),
barGraphics: <Widget>[
new _StatusBarGraphic(),
new _AppBarGraphic(),
new _TabBarGraphic()
]
),
new _TechniqueItem(
titleText: 'Flexible',
builder: (BuildContext context) => new FlexibleSpaceDemo(),
barGraphics: <Widget>[
new _StatusBarGraphic(),
new _AppBarGraphic(),
new _FlexibleSpaceGraphic()
]
)
]
)
)
);
}
}
// Copyright 2015 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 '../gallery/demo.dart';
const String _checkboxText =
"# Checkboxes\n"
"Checkboxes allow the user to select multiple options from a set.";
const String _checkboxCode = 'selectioncontrols_checkbox';
const String _radioText =
"# Radio buttons\n"
"Radio buttons allow the user to select one option from a set. Use radio "
"buttons for exclusive selection if you think that the user needs to see "
"all available options side-by-side.";
const String _radioCode = 'selectioncontrols_radio';
const String _switchText =
"# Switches\n"
"On/off switches toggle the state of a single settings option. The option "
"that the switch controls, as well as the state it’s in, should be made "
"clear from the corresponding inline label.";
const String _switchCode = 'selectioncontrols_switch';
class SelectionControlsDemo extends StatefulWidget {
static const String routeName = '/selection-controls';
@override
_SelectionControlsDemoState createState() => new _SelectionControlsDemoState();
}
class _SelectionControlsDemoState extends State<SelectionControlsDemo> {
@override
Widget build(BuildContext context) {
List<ComponentDemoTabData> demos = <ComponentDemoTabData>[
new ComponentDemoTabData(
tabName: "CHECKBOX",
description: _checkboxText,
widget: buildCheckbox(),
exampleCodeTag: _checkboxCode
),
new ComponentDemoTabData(
tabName: "RADIO",
description: _radioText,
widget: buildRadio(),
exampleCodeTag: _radioCode
),
new ComponentDemoTabData(
tabName: "SWITCH",
description: _switchText,
widget: buildSwitch(),
exampleCodeTag: _switchCode
)
];
return new TabbedComponentDemoScaffold(
title: 'Selection controls',
demos: demos
);
}
bool checkboxValueA = true;
bool checkboxValueB = false;
int radioValue = 0;
bool switchValue = false;
void handleRadioValueChanged(int value) {
setState(() {
radioValue = value;
});
}
Widget buildCheckbox() {
return new Align(
alignment: new FractionalOffset(0.5, 0.4),
child: new Column(
mainAxisAlignment: MainAxisAlignment.collapse,
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.collapse,
children: <Widget>[
new Checkbox(value: checkboxValueA, onChanged: (bool value) {
setState(() {
checkboxValueA = value;
});
}),
new Checkbox(value: checkboxValueB, onChanged: (bool value) {
setState(() {
checkboxValueB = value;
});
})
]
),
new Row(
mainAxisAlignment: MainAxisAlignment.collapse,
children: <Widget>[
// Disabled checkboxes
new Checkbox(value: true),
new Checkbox(value: false)
]
)
]
)
);
}
Widget buildRadio() {
return new Align(
alignment: new FractionalOffset(0.5, 0.4),
child: new Column(
mainAxisAlignment: MainAxisAlignment.collapse,
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.collapse,
children: <Widget>[
new Radio<int>(
value: 0,
groupValue: radioValue,
onChanged: handleRadioValueChanged
),
new Radio<int>(
value: 1,
groupValue: radioValue,
onChanged: handleRadioValueChanged
),
new Radio<int>(
value: 2,
groupValue: radioValue,
onChanged: handleRadioValueChanged
)
]
),
// Disabled radio buttons
new Row(
mainAxisAlignment: MainAxisAlignment.collapse,
children: <Widget>[
new Radio<int>(
value: 0,
groupValue: 0
),
new Radio<int>(
value: 1,
groupValue: 0
),
new Radio<int>(
value: 2,
groupValue: 0
)
]
)
]
)
);
}
Widget buildSwitch() {
return new Align(
alignment: new FractionalOffset(0.5, 0.4),
child: new Row(
mainAxisAlignment: MainAxisAlignment.collapse,
children: <Widget>[
new Switch(value: switchValue, onChanged: (bool value) {
setState(() {
switchValue = value;
});
}),
// Disabled switches
new Switch(value: true),
new Switch(value: false)
]
)
);
}
}
// Copyright 2015 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';
class SliderDemo extends StatefulWidget {
static const String routeName = '/slider';
@override
_SliderDemoState createState() => new _SliderDemoState();
}
class _SliderDemoState extends State<SliderDemo> {
double _value = 25.0;
double _discreteValue = 20.0;
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text('Sliders')),
body: new Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
new Center(
child: new Slider(
value: _value,
min: 0.0,
max: 100.0,
onChanged: (double value) {
setState(() {
_value = value;
});
}
)
),
new Center(child: new Slider(value: _value / 100.0)),
new Center(
child: new Slider(
value: _discreteValue,
min: 0.0,
max: 100.0,
divisions: 5,
label: '${_discreteValue.round()}',
onChanged: (double value) {
setState(() {
_discreteValue = value;
});
}
)
),
]
)
);
}
}
// 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';
const String _text1 =
"Snackbars provide lightweight feedback about an operation by "
"showing a brief message at the bottom of the screen. Snackbars "
"can contain an action.";
const String _text2 =
"Snackbars should contain a single line of text directly related "
"to the operation performed. They cannot contain icons.";
const String _text3 =
"By default snackbars automatically disappear after a few seconds ";
class SnackBarDemo extends StatefulWidget {
SnackBarDemo({ Key key }) : super(key: key);
static const String routeName = '/snack-bar';
@override
_SnackBarDemoState createState() => new _SnackBarDemoState();
}
class _SnackBarDemoState extends State<SnackBarDemo> {
int _snackBarIndex = 1;
Widget buildBody(BuildContext context) {
return new Padding(
padding: const EdgeInsets.all(24.0),
child: new Block(
children: <Widget>[
new Text(_text1),
new Text(_text2),
new Center(
child: new RaisedButton(
child: new Text('SHOW A SNACKBAR'),
onPressed: () {
final int thisSnackBarIndex = _snackBarIndex++;
Scaffold.of(context).showSnackBar(new SnackBar(
content: new Text('This is snackbar #$thisSnackBarIndex.'),
action: new SnackBarAction(
label: 'ACTION',
onPressed: () {
Scaffold.of(context).showSnackBar(new SnackBar(
content: new Text('You pressed snackbar $thisSnackBarIndex\'s action.')
));
}
)
));
}
)
),
new Text(_text3),
]
.map((Widget child) {
return new Container(
margin: const EdgeInsets.symmetric(vertical: 12.0),
child: child
);
})
.toList()
)
);
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Snackbar')
),
body: new Builder(
// Create an inner BuildContext so that the snackBar onPressed methods
// can refer to the Scaffold with Scaffold.of().
builder: buildBody
)
);
}
}
// Copyright 2015 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';
class _Page {
_Page({ this.label });
final GlobalKey<ScrollableState<Scrollable>> key = new GlobalKey<ScrollableState<Scrollable>>();
final String label;
}
final List<_Page> _pages = <_Page>[
new _Page(label: 'ONE'),
new _Page(label: 'TWO'),
new _Page(label: 'FREE'),
new _Page(label: 'FOUR')
];
class TabsDemo extends StatefulWidget {
static const String routeName = '/tabs';
@override
TabsDemoState createState() => new TabsDemoState();
}
class TabsDemoState extends State<TabsDemo> {
_Page _selectedPage;
double _scrollOffset = 0.0;
@override
void initState() {
super.initState();
_selectedPage = _pages[0];
}
@override
Widget build(BuildContext context) {
final double statusBarHeight = MediaQuery.of(context).padding.top;
return new TabBarSelection<_Page>(
values: _pages,
onChanged: (_Page value) {
setState(() {
_selectedPage = value;
_selectedPage.key.currentState.scrollTo(_scrollOffset);
});
},
child: new Scaffold(
appBarBehavior: AppBarBehavior.under,
appBar: new AppBar(
title: new Text('Tabs and scrolling'),
tabBar: new TabBar<_Page>(
labels: new Map<_Page, TabLabel>.fromIterable(_pages, value: (_Page page) {
return new TabLabel(text: page.label);
})
)
),
body: new TabBarView<_Page>(
children: _pages.map((_Page page) {
return new Block(
padding: new EdgeInsets.only(top: kTextTabBarHeight + kToolBarHeight + statusBarHeight),
scrollableKey: page.key,
onScroll: (double value) { _scrollOffset = value; },
children: new List<Widget>.generate(6, (int i) {
return new Container(
padding: const EdgeInsets.all(8.0),
height: 192.0,
child: new Card(
child: new Center(
child: new Text('Tab $page.label, item $i')
)
)
);
})
);
}).toList()
)
)
);
}
}
// Copyright 2015 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';
class _Page {
_Page({ this.label, this.colors, this.icon });
final String label;
final Map<int, Color> colors;
final IconData icon;
TabLabel get tabLabel => new TabLabel(text: label.toUpperCase());
Color get labelColor => colors != null ? colors[300] : Colors.grey[300];
bool get fabDefined => colors != null && icon != null;
Color get fabColor => colors[400];
Icon get fabIcon => new Icon(icon: icon);
Key get fabKey => new ValueKey<Color>(fabColor);
}
const String _explanatoryText =
"When the Scaffold's floating action button changes, the new button fades and "
"turns into view. In this demo, changing tabs can cause the app to be rebuilt "
"with a FloatingActionButton that the Scaffold distinguishes from the others "
"by its key.";
class TabsFabDemo extends StatefulWidget {
static const String routeName = '/tabs-fab';
@override
_TabsFabDemoState createState() => new _TabsFabDemoState();
}
class _TabsFabDemoState extends State<TabsFabDemo> {
final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
final List<_Page> pages = <_Page>[
new _Page(label: 'Blue', colors: Colors.indigo, icon: Icons.add),
new _Page(label: 'Eco', colors: Colors.green, icon: Icons.create),
new _Page(label: 'No'),
new _Page(label: 'Teal', colors: Colors.teal, icon: Icons.add),
new _Page(label: 'Red', colors: Colors.red, icon: Icons.create),
];
_Page selectedPage;
@override
void initState() {
super.initState();
selectedPage = pages[0];
}
void _handleTabSelection(_Page page) {
setState(() {
selectedPage = page;
});
}
void _showExplanatoryText() {
scaffoldKey.currentState.showBottomSheet((BuildContext context) {
return new Container(
decoration: new BoxDecoration(
border: new Border(top: new BorderSide(color: Theme.of(context).dividerColor))
),
child: new Padding(
padding: const EdgeInsets.all(32.0),
child: new Text(_explanatoryText, style: Theme.of(context).textTheme.subhead)
)
);
});
}
Widget buildTabView(_Page page) {
return new Builder(
builder: (BuildContext context) {
return new Container(
key: new ValueKey<String>(page.label),
padding: const EdgeInsets.fromLTRB(48.0, 48.0, 48.0, 96.0),
child: new Card(
child: new Center(
child: new Text(page.label,
style: new TextStyle(
color: page.labelColor,
fontSize: 32.0
),
textAlign: TextAlign.center
)
)
)
);
}
);
}
@override
Widget build(BuildContext context) {
return new TabBarSelection<_Page>(
values: pages,
onChanged: _handleTabSelection,
child: new Scaffold(
key: scaffoldKey,
appBar: new AppBar(
title: new Text('FAB per tab'),
tabBar: new TabBar<_Page>(
labels: new Map<_Page, TabLabel>.fromIterable(pages, value: (_Page page) => page.tabLabel)
)
),
floatingActionButton: !selectedPage.fabDefined ? null : new FloatingActionButton(
key: selectedPage.fabKey,
tooltip: 'Show explanation',
backgroundColor: selectedPage.fabColor,
child: selectedPage.fabIcon,
onPressed: _showExplanatoryText
),
body: new TabBarView<_Page>(children: pages.map(buildTabView).toList())
)
);
}
}
// 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';
class TextFieldDemo extends StatefulWidget {
TextFieldDemo({ Key key }) : super(key: key);
static const String routeName = '/text-field';
@override
TextFieldDemoState createState() => new TextFieldDemoState();
}
class PersonData {
String name;
String phoneNumber;
String password;
}
class TextFieldDemoState extends State<TextFieldDemo> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
PersonData person = new PersonData();
void showInSnackBar(String value) {
_scaffoldKey.currentState.showSnackBar(new SnackBar(
content: new Text(value)
));
}
void _handleSubmitted() {
showInSnackBar('${person.name}\'s phone number is ${person.phoneNumber}');
}
String _validateName(String value) {
if (value.isEmpty)
return 'Name is required.';
RegExp nameExp = new RegExp(r'^[A-za-z ]+$');
if (!nameExp.hasMatch(value))
return 'Please enter only alphabetical characters.';
return null;
}
String _validatePhoneNumber(String value) {
RegExp phoneExp = new RegExp(r'^\d\d\d-\d\d\d\-\d\d\d\d$');
if (!phoneExp.hasMatch(value))
return '###-###-#### - Please enter a valid phone number.';
return null;
}
String _validatePassword(String value) {
if (person.password == null || person.password.isEmpty)
return 'Please choose a password.';
if (person.password != value)
return 'Passwords don\'t match';
return null;
}
@override
Widget build(BuildContext context) {
return new Scaffold(
key: _scaffoldKey,
appBar: new AppBar(
title: new Text('Text fields')
),
body: new Form(
onSubmitted: _handleSubmitted,
child: new Block(
padding: const EdgeInsets.all(8.0),
children: <Widget>[
new Input(
hintText: 'What do people call you?',
labelText: 'Name',
formField: new FormField<String>(
// TODO(mpcomplete): replace with person#name=
setter: (String val) { person.name = val; },
validator: _validateName
)
),
new Input(
hintText: 'Where can we reach you?',
labelText: 'Phone Number',
formField: new FormField<String>(
setter: (String val) { person.phoneNumber = val; },
validator: _validatePhoneNumber
)
),
new Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Flexible(
child: new Input(
hintText: 'How do you log in?',
labelText: 'New Password',
hideText: true,
formField: new FormField<String>(
setter: (String val) { person.password = val; }
)
)
),
new Flexible(
child: new Input(
hintText: 'How do you log in?',
labelText: 'Re-type Password',
hideText: true,
formField: new FormField<String>(
validator: _validatePassword
)
)
)
]
)
]
)
)
);
}
}
// Copyright 2015 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 'dart:async';
import 'package:flutter/material.dart';
class TimePickerDemo extends StatefulWidget {
static const String routeName = '/time-picker';
@override
_TimePickerDemoState createState() => new _TimePickerDemoState();
}
class _TimePickerDemoState extends State<TimePickerDemo> {
TimeOfDay _selectedTime = const TimeOfDay(hour: 7, minute: 28);
Future<Null> _handleSelectTime() async {
TimeOfDay picked = await showTimePicker(
context: context,
initialTime: _selectedTime
);
if (picked != _selectedTime) {
setState(() {
_selectedTime = picked;
});
}
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text('Time picker')),
body: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text('$_selectedTime'),
new SizedBox(height: 20.0),
new RaisedButton(
onPressed: _handleSelectTime,
child: new Text('SELECT TIME')
),
]
)
);
}
}
// 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';
const String _introText =
"Tooltips are short identifying messages that briefly appear in response to "
"a long press. Tooltip messages are also used by services that make Flutter "
"apps accessible, like screen readers.";
class TooltipDemo extends StatelessWidget {
static const String routeName = '/tooltips';
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
return new Scaffold(
appBar: new AppBar(
title: new Text('Tooltips')
),
body: new Builder(
builder: (BuildContext context) {
return new Block(
children: <Widget>[
new Text(_introText, style: theme.textTheme.subhead),
new Row(
children: <Widget>[
new Text('Long press the ', style: theme.textTheme.subhead),
new Tooltip(
message: 'call icon',
child: new Icon(
size: 18.0,
icon: Icons.call,
color: theme.primaryColor
)
),
new Text(' icon.', style: theme.textTheme.subhead)
]
),
new Center(
child: new IconButton(
size: 48.0,
icon: Icons.call,
color: theme.primaryColor,
tooltip: 'place a phone call',
onPressed: () {
Scaffold.of(context).showSnackBar(new SnackBar(
content: new Text('That was an ordinary tap.')
));
}
)
)
]
.map((Widget widget) {
return new Padding(
padding: const EdgeInsets.only(top: 16.0, left: 16.0, right: 16.0),
child: widget
);
})
.toList()
);
}
)
);
}
}
// 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';
class TwoLevelListDemo extends StatelessWidget {
static const String routeName = '/two-level-list';
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text('Expand/collapse list control')),
body: new TwoLevelList(
type: MaterialListType.oneLine,
children: <Widget>[
new TwoLevelListItem(title: new Text('Top')),
new TwoLevelSublist(
title: new Text('Sublist'),
children: <Widget>[
new TwoLevelListItem(title: new Text('One')),
new TwoLevelListItem(title: new Text('Two')),
new TwoLevelListItem(title: new Text('Free')),
new TwoLevelListItem(title: new Text('Four'))
]
),
new TwoLevelListItem(title: new Text('Bottom'))
]
)
);
}
}
// 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 'dart:developer';
import 'package:flutter/material.dart';
typedef Widget GalleryDemoBuilder();
class GalleryItem extends StatelessWidget {
GalleryItem({ this.title, this.icon, this.routeName });
final String title;
final IconData icon;
final String routeName;
@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 (routeName != null) {
Timeline.instantSync('Start Transition', arguments: <String, String>{
'from': '/',
'to': routeName
});
Navigator.pushNamed(context, routeName);
}
}
);
}
}
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment