mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Gallery code snippets now analyzed (#3391)
* Gallery code snippets now analyzed
This commit is contained in:
parent
c294014d00
commit
f7360126b8
@ -37,3 +37,4 @@ assets:
|
||||
- packages/flutter_gallery_assets/landscape_9.jpg
|
||||
- packages/flutter_gallery_assets/landscape_10.jpg
|
||||
- packages/flutter_gallery_assets/landscape_11.jpg
|
||||
- lib/gallery/example_code.dart
|
||||
|
@ -11,21 +11,7 @@ const String _raisedText =
|
||||
"Raised buttons add dimension to mostly flat layouts. They emphasize "
|
||||
"functions on busy or wide spaces.";
|
||||
|
||||
const String _raisedCode =
|
||||
"""// Create a raised button.
|
||||
new RaisedButton(
|
||||
child: new Text('BUTTON TITLE'),
|
||||
onPressed: () {
|
||||
// Perform some action
|
||||
}
|
||||
);
|
||||
|
||||
// Create a disabled button.
|
||||
// Buttons are disabled when onPressed isn't
|
||||
// specified or is null.
|
||||
new RaisedButton(
|
||||
child: new Text('BUTTON TITLE')
|
||||
);""";
|
||||
const String _raisedCode = 'buttons_raised';
|
||||
|
||||
const String _flatText =
|
||||
"# Flat buttons\n"
|
||||
@ -33,21 +19,7 @@ const String _flatText =
|
||||
"but does not lift. Use flat buttons on toolbars, in dialogs and "
|
||||
"inline with padding";
|
||||
|
||||
const String _flatCode =
|
||||
"""// Create a flat button.
|
||||
new FlatButton(
|
||||
child: new Text('BUTTON TITLE'),
|
||||
onPressed: () {
|
||||
// Perform some action
|
||||
}
|
||||
);
|
||||
|
||||
// Create a disabled button.
|
||||
// Buttons are disabled when onPressed isn't
|
||||
// specified or is null.
|
||||
new FlatButton(
|
||||
child: new Text('BUTTON TITLE')
|
||||
);""";
|
||||
const String _flatCode = 'buttons_flat';
|
||||
|
||||
const String _dropdownText =
|
||||
"# Dropdown buttons\n"
|
||||
@ -55,46 +27,13 @@ const String _dropdownText =
|
||||
"small set of values. The button displays the current value and a down "
|
||||
"arrow.";
|
||||
|
||||
const String _dropdownCode =
|
||||
"""// Member variable holding value.
|
||||
String dropdownValue
|
||||
|
||||
// Drop down button with string values.
|
||||
new DropDownButton<String>(
|
||||
value: dropdownValue,
|
||||
onChanged: (String newValue) {
|
||||
// null indicates the user didn't select a
|
||||
// new value.
|
||||
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()
|
||||
)""";
|
||||
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 =
|
||||
"""// Member variable holding toggle value.
|
||||
bool value;
|
||||
|
||||
// Toggleable icon button.
|
||||
new IconButton(
|
||||
icon: Icons.thumb_up,
|
||||
onPressed: () {
|
||||
setState(() => value = !value);
|
||||
},
|
||||
color: value ? Theme.of(context).primaryColor : null
|
||||
)""";
|
||||
const String _iconCode = 'buttons_icon';
|
||||
|
||||
const String _actionText =
|
||||
"# Floating action buttons\n"
|
||||
@ -103,16 +42,7 @@ const String _actionText =
|
||||
"behaviors that include morphing, launching, and a transferring anchor "
|
||||
"point.";
|
||||
|
||||
const String _actionCode =
|
||||
"""// Floating action button in Scaffold.
|
||||
new Scaffold(
|
||||
appBar: new AppBar(
|
||||
title: new Text('Demo')
|
||||
),
|
||||
floatingActionButton: new FloatingActionButton(
|
||||
child: new Icon(icon: Icons.add)
|
||||
)
|
||||
);""";
|
||||
const String _actionCode = 'buttons_action';
|
||||
|
||||
class ButtonsDemo extends StatefulWidget {
|
||||
@override
|
||||
@ -127,32 +57,31 @@ class _ButtonsDemoState extends State<ButtonsDemo> {
|
||||
tabName: 'RAISED',
|
||||
description: _raisedText,
|
||||
widget: buildRaisedButton(),
|
||||
exampleCode: _raisedCode
|
||||
exampleCodeTag: _raisedCode
|
||||
),
|
||||
new ComponentDemoTabData(
|
||||
tabName: 'FLAT',
|
||||
description: _flatText,
|
||||
widget: buildFlatButton(),
|
||||
exampleCode: _flatCode
|
||||
exampleCodeTag: _flatCode
|
||||
),
|
||||
new ComponentDemoTabData(
|
||||
tabName: 'DROPDOWN',
|
||||
description: _dropdownText,
|
||||
widget: buildDropdownButton(),
|
||||
exampleCode:
|
||||
_dropdownCode
|
||||
exampleCodeTag: _dropdownCode
|
||||
),
|
||||
new ComponentDemoTabData(
|
||||
tabName: 'ICON',
|
||||
description: _iconText,
|
||||
widget: buildIconButton(),
|
||||
exampleCode: _iconCode
|
||||
exampleCodeTag: _iconCode
|
||||
),
|
||||
new ComponentDemoTabData(
|
||||
tabName: 'ACTION',
|
||||
description: _actionText,
|
||||
widget: buildActionButton(),
|
||||
exampleCode: _actionCode
|
||||
exampleCodeTag: _actionCode
|
||||
),
|
||||
];
|
||||
|
||||
|
@ -9,35 +9,7 @@ import 'package:flutter/widgets.dart';
|
||||
|
||||
import '../gallery/demo.dart';
|
||||
|
||||
const String _kExampleCode =
|
||||
"""// Creates a scrollable grid list with images
|
||||
// loaded from the web.
|
||||
new ScrollableGrid(
|
||||
delegate: new FixedColumnCountGridDelegate(
|
||||
columnCount: 3,
|
||||
tileAspectRatio: 1.0,
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
columnSpacing: 4.0,
|
||||
rowSpacing: 4.0
|
||||
),
|
||||
children: <String>[
|
||||
'https://example.com/image-0.jpg',
|
||||
'https://example.com/image-1.jpg',
|
||||
'https://example.com/image-2.jpg',
|
||||
...
|
||||
'https://example.com/image-n.jpg'
|
||||
].map((String url) {
|
||||
return new GridTile(
|
||||
footer: new GridTileBar(
|
||||
title: new Text(url)
|
||||
),
|
||||
child: new NetworkImage(
|
||||
src: url,
|
||||
fit: ImageFit.cover
|
||||
)
|
||||
);
|
||||
})
|
||||
);""";
|
||||
const String _kExampleCode = 'gridlists';
|
||||
|
||||
enum GridDemoTileStyle {
|
||||
imageOnly,
|
||||
@ -301,7 +273,7 @@ class GridListDemoState extends State<GridListDemo> {
|
||||
)
|
||||
),
|
||||
new DemoBottomBar(
|
||||
exampleCode: _kExampleCode
|
||||
exampleCodeTag: _kExampleCode
|
||||
)
|
||||
]
|
||||
)
|
||||
|
@ -10,24 +10,7 @@ const String _checkboxText =
|
||||
"# Checkboxes\n"
|
||||
"Checkboxes allow the user to select multiple options from a set.";
|
||||
|
||||
const String _checkboxCode =
|
||||
"""// Member variable holding the checkbox's value.
|
||||
bool checkboxValue = false;
|
||||
|
||||
// Create a checkbox.
|
||||
new Checkbox(
|
||||
value: checkboxValue,
|
||||
onChanged: (bool value) {
|
||||
setState(() {
|
||||
checkboxValue = value;
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
// Create a disabled checkbox.
|
||||
// Checkboxes are disabled when onChanged isn't
|
||||
// specified or null.
|
||||
new Checkbox(value: false)""";
|
||||
const String _checkboxCode = 'selectioncontrols_checkbox';
|
||||
|
||||
const String _radioText =
|
||||
"# Radio buttons\n"
|
||||
@ -35,43 +18,7 @@ const String _radioText =
|
||||
"buttons for exclusive selection if you think that the user needs to see "
|
||||
"all available options side-by-side.";
|
||||
|
||||
const String _radioCode =
|
||||
"""// Member variable holding value.
|
||||
int radioValue = 0;
|
||||
|
||||
// Method setting value.
|
||||
void handleRadioValueChanged(int value) {
|
||||
setState(() {
|
||||
radioValue = value;
|
||||
});
|
||||
}
|
||||
|
||||
// Creates a set of radio buttons.
|
||||
new Row(
|
||||
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
|
||||
)
|
||||
]
|
||||
);
|
||||
|
||||
// Creates a disabled radio button.
|
||||
new Radio<int>(
|
||||
value: 0,
|
||||
groupValue: 0
|
||||
);""";
|
||||
const String _radioCode = 'selectioncontrols_radio';
|
||||
|
||||
const String _switchText =
|
||||
"# Switches\n"
|
||||
@ -79,24 +26,7 @@ const String _switchText =
|
||||
"that the switch controls, as well as the state it’s in, should be made "
|
||||
"clear from the corresponding inline label.";
|
||||
|
||||
const String _switchCode =
|
||||
"""// Member variable holding value.
|
||||
bool switchValue = false;
|
||||
|
||||
// Create a switch.
|
||||
new Switch(
|
||||
value: switchValue,
|
||||
onChanged: (bool value) {
|
||||
setState(() {
|
||||
switchValue = value;
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
// Create a disabled switch.
|
||||
// Switches are disabled when onChanged isn't
|
||||
// specified or null.
|
||||
new Switch(value: false)""";
|
||||
const String _switchCode = 'selectioncontrols_switch';
|
||||
|
||||
class SelectionControlsDemo extends StatefulWidget {
|
||||
@override
|
||||
@ -111,19 +41,19 @@ class _SelectionControlsDemoState extends State<SelectionControlsDemo> {
|
||||
tabName: "CHECKBOX",
|
||||
description: _checkboxText,
|
||||
widget: buildCheckbox(),
|
||||
exampleCode: _checkboxCode
|
||||
exampleCodeTag: _checkboxCode
|
||||
),
|
||||
new ComponentDemoTabData(
|
||||
tabName: "RADIO",
|
||||
description: _radioText,
|
||||
widget: buildRadio(),
|
||||
exampleCode: _radioCode
|
||||
exampleCodeTag: _radioCode
|
||||
),
|
||||
new ComponentDemoTabData(
|
||||
tabName: "SWITCH",
|
||||
description: _switchText,
|
||||
widget: buildSwitch(),
|
||||
exampleCode: _switchCode
|
||||
exampleCodeTag: _switchCode
|
||||
)
|
||||
];
|
||||
|
||||
|
@ -5,18 +5,19 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
|
||||
import '../gallery/syntax_highlighter.dart';
|
||||
import 'syntax_highlighter.dart';
|
||||
import 'example_code_parser.dart';
|
||||
|
||||
class SingleComponentDemoData {
|
||||
SingleComponentDemoData({
|
||||
this.widget,
|
||||
this.exampleCode,
|
||||
this.exampleCodeTag,
|
||||
this.description,
|
||||
this.onPressedDemo
|
||||
});
|
||||
|
||||
final Widget widget;
|
||||
final String exampleCode;
|
||||
final String exampleCodeTag;
|
||||
final String description;
|
||||
final VoidCallback onPressedDemo;
|
||||
}
|
||||
@ -24,13 +25,13 @@ class SingleComponentDemoData {
|
||||
class ComponentDemoTabData extends SingleComponentDemoData {
|
||||
ComponentDemoTabData({
|
||||
Widget widget,
|
||||
String exampleCode,
|
||||
String exampleCodeTag,
|
||||
String description,
|
||||
VoidCallback onPressedDemo,
|
||||
this.tabName
|
||||
}) : super(
|
||||
widget: widget,
|
||||
exampleCode: exampleCode,
|
||||
exampleCodeTag: exampleCodeTag,
|
||||
description: description,
|
||||
onPressedDemo: onPressedDemo
|
||||
);
|
||||
@ -117,7 +118,7 @@ class SingleComponentDemo extends StatelessWidget {
|
||||
child: demo.widget
|
||||
),
|
||||
new DemoBottomBar(
|
||||
exampleCode: demo.exampleCode,
|
||||
exampleCodeTag: demo.exampleCodeTag,
|
||||
onPressedDemo: demo.onPressedDemo
|
||||
)
|
||||
]
|
||||
@ -126,18 +127,18 @@ class SingleComponentDemo extends StatelessWidget {
|
||||
}
|
||||
|
||||
class DemoBottomBar extends StatelessWidget {
|
||||
DemoBottomBar({ this.exampleCode, this.onPressedDemo });
|
||||
DemoBottomBar({ this.exampleCodeTag, this.onPressedDemo });
|
||||
|
||||
final String exampleCode;
|
||||
final String exampleCodeTag;
|
||||
final VoidCallback onPressedDemo;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
VoidCallback onPressedCode;
|
||||
if (exampleCode != null) {
|
||||
if (exampleCodeTag != null) {
|
||||
onPressedCode = () {
|
||||
Navigator.push(context, new MaterialPageRoute<FullScreenCodeDialog>(
|
||||
builder: (BuildContext context) => new FullScreenCodeDialog(code: exampleCode)
|
||||
builder: (BuildContext context) => new FullScreenCodeDialog(exampleCodeTag: exampleCodeTag)
|
||||
));
|
||||
};
|
||||
}
|
||||
@ -185,9 +186,9 @@ class DemoBottomBar extends StatelessWidget {
|
||||
}
|
||||
|
||||
class FormattedCode extends StatefulWidget {
|
||||
FormattedCode(this.code);
|
||||
FormattedCode(this.exampleCode);
|
||||
|
||||
final String code;
|
||||
final String exampleCode;
|
||||
|
||||
@override
|
||||
_FormattedCodeState createState() => new _FormattedCodeState();
|
||||
@ -211,25 +212,58 @@ class _FormattedCodeState extends State<FormattedCode> {
|
||||
void didUpdateConfig(FormattedCode oldConfig) {
|
||||
super.didUpdateConfig(oldConfig);
|
||||
|
||||
if (oldConfig.code != config.code)
|
||||
if (oldConfig.exampleCode != config.exampleCode)
|
||||
_formatText();
|
||||
}
|
||||
|
||||
void _formatText() {
|
||||
_formattedText = new TextSpan(
|
||||
style: new TextStyle(fontFamily: 'monospace', fontSize: 10.0),
|
||||
children: <TextSpan>[new DartSyntaxHighlighter().format(config.code)]
|
||||
children: <TextSpan>[new DartSyntaxHighlighter().format(config.exampleCode)]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class FullScreenCodeDialog extends StatelessWidget {
|
||||
FullScreenCodeDialog({ this.code });
|
||||
class FullScreenCodeDialog extends StatefulWidget {
|
||||
FullScreenCodeDialog({ this.exampleCodeTag });
|
||||
|
||||
final String code;
|
||||
final String exampleCodeTag;
|
||||
|
||||
@override
|
||||
FullScreenCodeDialogState createState() => new FullScreenCodeDialogState();
|
||||
}
|
||||
|
||||
class FullScreenCodeDialogState extends State<FullScreenCodeDialog> {
|
||||
|
||||
String _exampleCode;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
getExampleCode(config.exampleCodeTag, DefaultAssetBundle.of(context)).then((String code) {
|
||||
setState(() {
|
||||
_exampleCode = code;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget body;
|
||||
if (_exampleCode == null) {
|
||||
body = new Center(
|
||||
child: new CircularProgressIndicator()
|
||||
);
|
||||
} else {
|
||||
body = new ScrollableViewport(
|
||||
child: new Padding(
|
||||
padding: new EdgeInsets.all(16.0),
|
||||
child: new FormattedCode(_exampleCode)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return new Scaffold(
|
||||
appBar: new AppBar(
|
||||
leading: new IconButton(
|
||||
@ -238,12 +272,7 @@ class FullScreenCodeDialog extends StatelessWidget {
|
||||
),
|
||||
title: new Text('Example Code')
|
||||
),
|
||||
body: new ScrollableViewport(
|
||||
child: new Padding(
|
||||
padding: new EdgeInsets.all(16.0),
|
||||
child: new FormattedCode(code)
|
||||
)
|
||||
)
|
||||
body: body
|
||||
);
|
||||
}
|
||||
}
|
||||
|
230
examples/material_gallery/lib/gallery/example_code.dart
Normal file
230
examples/material_gallery/lib/gallery/example_code.dart
Normal file
@ -0,0 +1,230 @@
|
||||
// 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.
|
||||
|
||||
// Note: This code is not runnable, it contains code snippets displayed in the
|
||||
// gallery.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ButtonsDemo {
|
||||
void setState(VoidCallback callback) { }
|
||||
BuildContext context;
|
||||
|
||||
void buttons() {
|
||||
|
||||
// START buttons_raised
|
||||
// Create a raised button.
|
||||
new RaisedButton(
|
||||
child: new Text('BUTTON TITLE'),
|
||||
onPressed: () {
|
||||
// Perform some action
|
||||
}
|
||||
);
|
||||
|
||||
// Create a disabled button.
|
||||
// Buttons are disabled when onPressed isn't
|
||||
// specified or is null.
|
||||
new RaisedButton(
|
||||
child: new Text('BUTTON TITLE')
|
||||
);
|
||||
// END
|
||||
|
||||
|
||||
// START buttons_flat
|
||||
// Create a flat button.
|
||||
new FlatButton(
|
||||
child: new Text('BUTTON TITLE'),
|
||||
onPressed: () {
|
||||
// Perform some action
|
||||
}
|
||||
);
|
||||
|
||||
// Create a disabled button.
|
||||
// Buttons are disabled when onPressed isn't
|
||||
// specified or is null.
|
||||
new FlatButton(
|
||||
child: new Text('BUTTON TITLE')
|
||||
);
|
||||
// END
|
||||
|
||||
|
||||
// START buttons_dropdown
|
||||
// Member variable holding value.
|
||||
String dropdownValue;
|
||||
|
||||
// Drop down button with string values.
|
||||
new DropDownButton<String>(
|
||||
value: dropdownValue,
|
||||
onChanged: (String newValue) {
|
||||
// null indicates the user didn't select a
|
||||
// new value.
|
||||
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()
|
||||
);
|
||||
// END
|
||||
|
||||
|
||||
// START buttons_icon
|
||||
// Member variable holding toggle value.
|
||||
bool value;
|
||||
|
||||
// Toggleable icon button.
|
||||
new IconButton(
|
||||
icon: Icons.thumb_up,
|
||||
onPressed: () {
|
||||
setState(() => value = !value);
|
||||
},
|
||||
color: value ? Theme.of(context).primaryColor : null
|
||||
);
|
||||
// END
|
||||
|
||||
|
||||
// START buttons_action
|
||||
// Floating action button in Scaffold.
|
||||
new Scaffold(
|
||||
appBar: new AppBar(
|
||||
title: new Text('Demo')
|
||||
),
|
||||
floatingActionButton: new FloatingActionButton(
|
||||
child: new Icon(icon: Icons.add)
|
||||
)
|
||||
);
|
||||
// END
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class SelectionControls {
|
||||
void setState(VoidCallback callback) { }
|
||||
|
||||
void selectionControls() {
|
||||
|
||||
// START selectioncontrols_checkbox
|
||||
// Member variable holding the checkbox's value.
|
||||
bool checkboxValue = false;
|
||||
|
||||
// Create a checkbox.
|
||||
new Checkbox(
|
||||
value: checkboxValue,
|
||||
onChanged: (bool value) {
|
||||
setState(() {
|
||||
checkboxValue = value;
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// Create a disabled checkbox.
|
||||
// Checkboxes are disabled when onChanged isn't
|
||||
// specified or null.
|
||||
new Checkbox(value: false);
|
||||
// END
|
||||
|
||||
|
||||
// START selectioncontrols_radio
|
||||
// Member variable holding value.
|
||||
int radioValue = 0;
|
||||
|
||||
// Method setting value.
|
||||
void handleRadioValueChanged(int value) {
|
||||
setState(() {
|
||||
radioValue = value;
|
||||
});
|
||||
}
|
||||
|
||||
// Creates a set of radio buttons.
|
||||
new Row(
|
||||
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
|
||||
)
|
||||
]
|
||||
);
|
||||
|
||||
// Creates a disabled radio button.
|
||||
new Radio<int>(
|
||||
value: 0,
|
||||
groupValue: 0
|
||||
);
|
||||
// END
|
||||
|
||||
|
||||
// START selectioncontrols_switch
|
||||
// Member variable holding value.
|
||||
bool switchValue = false;
|
||||
|
||||
// Create a switch.
|
||||
new Switch(
|
||||
value: switchValue,
|
||||
onChanged: (bool value) {
|
||||
setState(() {
|
||||
switchValue = value;
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// Create a disabled switch.
|
||||
// Switches are disabled when onChanged isn't
|
||||
// specified or null.
|
||||
new Switch(value: false);
|
||||
// END
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class GridLists {
|
||||
void gridlists() {
|
||||
// START gridlists
|
||||
// Creates a scrollable grid list with images
|
||||
// loaded from the web.
|
||||
new ScrollableGrid(
|
||||
delegate: new FixedColumnCountGridDelegate(
|
||||
columnCount: 3,
|
||||
tileAspectRatio: 1.0,
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
columnSpacing: 4.0,
|
||||
rowSpacing: 4.0
|
||||
),
|
||||
children: <String>[
|
||||
'https://example.com/image-0.jpg',
|
||||
'https://example.com/image-1.jpg',
|
||||
'https://example.com/image-2.jpg',
|
||||
'...',
|
||||
'https://example.com/image-n.jpg'
|
||||
].map((String url) {
|
||||
return new GridTile(
|
||||
footer: new GridTileBar(
|
||||
title: new Text(url)
|
||||
),
|
||||
child: new NetworkImage(
|
||||
src: url,
|
||||
fit: ImageFit.cover
|
||||
)
|
||||
);
|
||||
})
|
||||
);
|
||||
// END
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
// 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/services.dart';
|
||||
|
||||
const String _kStartTag = '// START ';
|
||||
const String _kEndTag = '// END';
|
||||
|
||||
Map<String, String> _exampleCode;
|
||||
|
||||
Future<String> getExampleCode(String tag, AssetBundle bundle) async {
|
||||
print('getExampleCode tag: $tag bundle: $bundle');
|
||||
|
||||
if (_exampleCode == null)
|
||||
await _parseExampleCode(bundle);
|
||||
|
||||
return _exampleCode[tag];
|
||||
}
|
||||
|
||||
Future<Null> _parseExampleCode(AssetBundle bundle) async {
|
||||
final String code = await bundle.loadString('lib/gallery/example_code.dart');
|
||||
_exampleCode = <String, String>{};
|
||||
|
||||
final List<String> lines = code.split('\n');
|
||||
|
||||
List<String> codeBlock;
|
||||
String codeTag;
|
||||
|
||||
for (String line in lines) {
|
||||
if (codeBlock == null) {
|
||||
// Outside a block.
|
||||
if (line.startsWith(_kStartTag)) {
|
||||
// Starting a new code block.
|
||||
codeBlock = <String>[];
|
||||
codeTag = line.substring(_kStartTag.length);
|
||||
} else {
|
||||
// Just skipping the line.
|
||||
}
|
||||
} else {
|
||||
// Inside a block.
|
||||
if (line.startsWith(_kEndTag)) {
|
||||
// Add the block.
|
||||
_exampleCode[codeTag] = codeBlock.join('\n');
|
||||
codeBlock = null;
|
||||
codeTag = null;
|
||||
} else {
|
||||
// Add to the current block
|
||||
codeBlock.add(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
53
examples/material_gallery/test/example_code_parser_test.dart
Normal file
53
examples/material_gallery/test/example_code_parser_test.dart
Normal file
@ -0,0 +1,53 @@
|
||||
// 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/services.dart';
|
||||
import 'package:mojo/core.dart' as core;
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../lib/gallery/example_code_parser.dart';
|
||||
|
||||
void main() {
|
||||
test('Material Gallery example code parser test', () async {
|
||||
TestAssetBundle bundle = new TestAssetBundle();
|
||||
|
||||
String codeSnippet0 = await getExampleCode('test_0', bundle);
|
||||
expect(codeSnippet0, 'test 0 0\ntest 0 1');
|
||||
|
||||
String codeSnippet1 = await getExampleCode('test_1', bundle);
|
||||
expect(codeSnippet1, 'test 1 0\ntest 1 1');
|
||||
});
|
||||
}
|
||||
|
||||
const String testCodeFile = """// A fake test file
|
||||
// START test_0
|
||||
test 0 0
|
||||
test 0 1
|
||||
// END
|
||||
|
||||
// Some comments
|
||||
// START test_1
|
||||
test 1 0
|
||||
test 1 1
|
||||
// END
|
||||
""";
|
||||
|
||||
class TestAssetBundle extends AssetBundle {
|
||||
@override
|
||||
ImageResource loadImage(String key) => null;
|
||||
|
||||
@override
|
||||
Future<String> loadString(String key) {if (key == 'lib/gallery/example_code.dart')
|
||||
return (new Completer<String>()..complete(testCodeFile)).future;
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<core.MojoDataPipeConsumer> load(String key) => null;
|
||||
|
||||
@override
|
||||
String toString() => '$runtimeType@$hashCode()';
|
||||
}
|
@ -241,6 +241,7 @@ class DropDownMenuItem<T> extends StatelessWidget {
|
||||
child: new DefaultTextStyle(
|
||||
style: Theme.of(context).textTheme.subhead,
|
||||
child: new Baseline(
|
||||
baselineType: TextBaseline.alphabetic,
|
||||
baseline: _kMenuItemHeight - _kBaselineOffsetFromBottom,
|
||||
child: child
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user