Commit 606f5622 authored by Hans Muller's avatar Hans Muller Committed by GitHub

Eliminated DrawerItem, use ListTile instead (#8992)

parent 51ea62c1
......@@ -577,53 +577,41 @@ class GalleryDrawer extends StatelessWidget {
child: new ListView(
children: <Widget>[
new FancyDrawerHeader(),
new DrawerItem(
icon: new Icon(Icons.brightness_5),
onPressed: () { _changeTheme(context, true); },
new ListTile(
leading: new Icon(Icons.brightness_5),
title: new Text('Light'),
onTap: () { _changeTheme(context, true); },
selected: ComplexLayoutApp.of(context).lightTheme,
child: new Row(
children: <Widget>[
new Expanded(child: new Text('Light')),
new Radio<bool>(
value: true,
groupValue: ComplexLayoutApp.of(context).lightTheme,
onChanged: (bool value) { _changeTheme(context, value); }
)
]
)
trailing: new Radio<bool>(
value: true,
groupValue: ComplexLayoutApp.of(context).lightTheme,
onChanged: (bool value) { _changeTheme(context, value); }
),
),
new DrawerItem(
icon: new Icon(Icons.brightness_7),
onPressed: () { _changeTheme(context, false); },
new ListTile(
leading: new Icon(Icons.brightness_7),
title: new Text('Dark'),
onTap: () { _changeTheme(context, false); },
selected: !ComplexLayoutApp.of(context).lightTheme,
child: new Row(
children: <Widget>[
new Expanded(child: new Text('Dark')),
new Radio<bool>(
value: false,
groupValue: ComplexLayoutApp.of(context).lightTheme,
onChanged: (bool value) { _changeTheme(context, value); }
)
]
)
trailing: new Radio<bool>(
value: false,
groupValue: ComplexLayoutApp.of(context).lightTheme,
onChanged: (bool value) { _changeTheme(context, value); },
),
),
new Divider(),
new DrawerItem(
icon: new Icon(Icons.hourglass_empty),
new ListTile(
leading: new Icon(Icons.hourglass_empty),
title: new Text('Animate Slowly'),
selected: timeDilation != 1.0,
onPressed: () { ComplexLayoutApp.of(context).toggleAnimationSpeed(); },
child: new Row(
children: <Widget>[
new Expanded(child: new Text('Animate Slowly')),
new Checkbox(
value: timeDilation != 1.0,
onChanged: (bool value) { ComplexLayoutApp.of(context).toggleAnimationSpeed(); }
)
]
)
)
]
)
onTap: () { ComplexLayoutApp.of(context).toggleAnimationSpeed(); },
trailing: new Checkbox(
value: timeDilation != 1.0,
onChanged: (bool value) { ComplexLayoutApp.of(context).toggleAnimationSpeed(); }
),
),
],
),
);
}
}
......
......@@ -107,10 +107,10 @@ class CardCollectionState extends State<CardCollection> {
buildFontRadioItem("Center-align text", TextAlign.center, _textAlign, _changeTextAlign, icon: Icons.format_align_center, enabled: !_editable),
buildFontRadioItem("Right-align text", TextAlign.right, _textAlign, _changeTextAlign, icon: Icons.format_align_right, enabled: !_editable),
new Divider(),
new DrawerItem(
icon: new Icon(Icons.dvr),
onPressed: () { debugDumpApp(); debugDumpRenderTree(); },
child: new Text('Dump App to Console'),
new ListTile(
leading: new Icon(Icons.dvr),
onTap: () { debugDumpApp(); debugDumpRenderTree(); },
title: new Text('Dump App to Console'),
),
],
),
......@@ -167,67 +167,51 @@ class CardCollectionState extends State<CardCollection> {
}
Widget buildDrawerCheckbox(String label, bool value, void callback(), { bool enabled: true }) {
return new DrawerItem(
onPressed: enabled ? callback : null,
child: new Row(
children: <Widget>[
new Expanded(child: new Text(label)),
new Checkbox(
value: value,
onChanged: enabled ? (_) { callback(); } : null,
),
],
return new ListTile(
onTap: enabled ? callback : null,
title: new Text(label),
trailing: new Checkbox(
value: value,
onChanged: enabled ? (_) { callback(); } : null,
),
);
}
Widget buildDrawerColorRadioItem(String label, MaterialColor itemValue, MaterialColor currentValue, ValueChanged<MaterialColor> onChanged, { IconData icon, bool enabled: true }) {
return new DrawerItem(
icon: new Icon(icon),
onPressed: enabled ? () { onChanged(itemValue); } : null,
child: new Row(
children: <Widget>[
new Expanded(child: new Text(label)),
new Radio<MaterialColor>(
value: itemValue,
groupValue: currentValue,
onChanged: enabled ? onChanged : null,
),
],
return new ListTile(
leading: new Icon(icon),
title: new Text(label),
onTap: enabled ? () { onChanged(itemValue); } : null,
trailing: new Radio<MaterialColor>(
value: itemValue,
groupValue: currentValue,
onChanged: enabled ? onChanged : null,
),
);
}
Widget buildDrawerDirectionRadioItem(String label, DismissDirection itemValue, DismissDirection currentValue, ValueChanged<DismissDirection> onChanged, { IconData icon, bool enabled: true }) {
return new DrawerItem(
icon: new Icon(icon),
onPressed: enabled ? () { onChanged(itemValue); } : null,
child: new Row(
children: <Widget>[
new Expanded(child: new Text(label)),
new Radio<DismissDirection>(
value: itemValue,
groupValue: currentValue,
onChanged: enabled ? onChanged : null,
),
],
return new ListTile(
leading: new Icon(icon),
title: new Text(label),
onTap: enabled ? () { onChanged(itemValue); } : null,
trailing: new Radio<DismissDirection>(
value: itemValue,
groupValue: currentValue,
onChanged: enabled ? onChanged : null,
),
);
}
Widget buildFontRadioItem(String label, TextAlign itemValue, TextAlign currentValue, ValueChanged<TextAlign> onChanged, { IconData icon, bool enabled: true }) {
return new DrawerItem(
icon: new Icon(icon),
onPressed: enabled ? () { onChanged(itemValue); } : null,
child: new Row(
children: <Widget>[
new Expanded(child: new Text(label)),
new Radio<TextAlign>(
value: itemValue,
groupValue: currentValue,
onChanged: enabled ? onChanged : null,
),
],
return new ListTile(
leading: new Icon(icon),
title: new Text(label),
onTap: enabled ? () { onChanged(itemValue); } : null,
trailing: new Radio<TextAlign>(
value: itemValue,
groupValue: currentValue,
onChanged: enabled ? onChanged : null,
),
);
}
......
......@@ -85,27 +85,23 @@ class PageViewAppState extends State<PageViewApp> {
child: new ListView(
children: <Widget>[
new DrawerHeader(child: new Center(child: new Text('Options'))),
new DrawerItem(
icon: new Icon(Icons.more_horiz),
new ListTile(
leading: new Icon(Icons.more_horiz),
selected: scrollDirection == Axis.horizontal,
child: new Text('Horizontal Layout'),
onPressed: switchScrollDirection,
trailing: new Text('Horizontal Layout'),
onTap: switchScrollDirection,
),
new DrawerItem(
icon: new Icon(Icons.more_vert),
new ListTile(
leading: new Icon(Icons.more_vert),
selected: scrollDirection == Axis.vertical,
child: new Text('Vertical Layout'),
onPressed: switchScrollDirection,
trailing: new Text('Vertical Layout'),
onTap: switchScrollDirection,
),
new DrawerItem(
onPressed: toggleItemsWrap,
child: new Row(
children: <Widget>[
new Expanded(child: new Text('Scrolling wraps around')),
// TODO(abarth): Actually make this checkbox change this value.
new Checkbox(value: itemsWrap, onChanged: null),
],
),
new ListTile(
onTap: toggleItemsWrap,
title: new Text('Scrolling wraps around'),
// TODO(abarth): Actually make this checkbox change this value.
trailing: new Checkbox(value: itemsWrap, onChanged: null),
),
],
),
......
......@@ -116,10 +116,10 @@ class _DrawerDemoState extends State<DrawerDemo> with TickerProviderStateMixin {
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: _drawerContents.map((String id) {
return new DrawerItem(
icon: new CircleAvatar(child: new Text(id)),
child: new Text('Drawer item $id'),
onPressed: _showNotImplementedMessage,
return new ListTile(
leading: new CircleAvatar(child: new Text(id)),
title: new Text('Drawer item $id'),
onTap: _showNotImplementedMessage,
);
}).toList(),
),
......@@ -133,15 +133,15 @@ class _DrawerDemoState extends State<DrawerDemo> with TickerProviderStateMixin {
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new DrawerItem(
icon: new Icon(Icons.add),
child: new Text('Add account'),
onPressed: _showNotImplementedMessage,
new ListTile(
leading: new Icon(Icons.add),
title: new Text('Add account'),
onTap: _showNotImplementedMessage,
),
new DrawerItem(
icon: new Icon(Icons.settings),
child: new Text('Manage accounts'),
onPressed: _showNotImplementedMessage,
new ListTile(
leading: new Icon(Icons.settings),
title: new Text('Manage accounts'),
onTap: _showNotImplementedMessage,
),
],
),
......
......@@ -126,96 +126,88 @@ class GalleryDrawer extends StatelessWidget {
final TextStyle aboutTextStyle = themeData.textTheme.body2;
final TextStyle linkStyle = themeData.textTheme.body2.copyWith(color: themeData.accentColor);
final Widget lightThemeItem = new DrawerItem(
icon: new Icon(Icons.brightness_5),
onPressed: () { onThemeChanged(true); },
final Widget lightThemeItem = new ListTile(
leading: new Icon(Icons.brightness_5),
title: new Text('Light'),
trailing: new Radio<bool>(
value: true,
groupValue: useLightTheme,
onChanged: onThemeChanged,
),
selected: useLightTheme,
child: new Row(
children: <Widget>[
new Expanded(child: new Text('Light')),
new Radio<bool>(
value: true,
groupValue: useLightTheme,
onChanged: onThemeChanged
)
]
)
onTap: () {
onThemeChanged(true);
},
);
final Widget darkThemeItem = new DrawerItem(
icon: new Icon(Icons.brightness_7),
onPressed: () { onThemeChanged(false); },
selected: useLightTheme,
child: new Row(
children: <Widget>[
new Expanded(child: new Text('Dark')),
new Radio<bool>(
value: false,
groupValue: useLightTheme,
onChanged: onThemeChanged
)
]
)
final Widget darkThemeItem = new ListTile(
leading: new Icon(Icons.brightness_7),
title: new Text('Dark'),
trailing: new Radio<bool>(
value: false,
groupValue: useLightTheme,
onChanged: onThemeChanged
),
selected: !useLightTheme,
onTap: () {
onThemeChanged(false);
},
);
final Widget mountainViewItem = new DrawerItem(
final Widget mountainViewItem = new ListTile(
// on iOS, we don't want to show an Android phone icon
icon: new Icon(defaultTargetPlatform == TargetPlatform.iOS ? Icons.star : Icons.phone_android),
onPressed: () { onPlatformChanged(TargetPlatform.android); },
leading: new Icon(defaultTargetPlatform == TargetPlatform.iOS ? Icons.star : Icons.phone_android),
title: new Text('Android'),
trailing: new Radio<TargetPlatform>(
value: TargetPlatform.android,
groupValue: Theme.of(context).platform,
onChanged: onPlatformChanged,
),
selected: Theme.of(context).platform == TargetPlatform.android,
child: new Row(
children: <Widget>[
new Expanded(child: new Text('Android')),
new Radio<TargetPlatform>(
value: TargetPlatform.android,
groupValue: Theme.of(context).platform,
onChanged: onPlatformChanged,
)
]
)
onTap: () {
onPlatformChanged(TargetPlatform.android);
},
);
final Widget cupertinoItem = new DrawerItem(
final Widget cupertinoItem = new ListTile(
// on iOS, we don't want to show the iPhone icon
icon: new Icon(defaultTargetPlatform == TargetPlatform.iOS ? Icons.star_border : Icons.phone_iphone),
onPressed: () { onPlatformChanged(TargetPlatform.iOS); },
leading: new Icon(defaultTargetPlatform == TargetPlatform.iOS ? Icons.star_border : Icons.phone_iphone),
title: new Text('iOS'),
trailing: new Radio<TargetPlatform>(
value: TargetPlatform.iOS,
groupValue: Theme.of(context).platform,
onChanged: onPlatformChanged,
),
selected: Theme.of(context).platform == TargetPlatform.iOS,
child: new Row(
children: <Widget>[
new Expanded(child: new Text('iOS')),
new Radio<TargetPlatform>(
value: TargetPlatform.iOS,
groupValue: Theme.of(context).platform,
onChanged: onPlatformChanged,
)
]
)
onTap: () {
onPlatformChanged(TargetPlatform.iOS);
},
);
final Widget animateSlowlyItem = new DrawerItem(
icon: new Icon(Icons.hourglass_empty),
final Widget animateSlowlyItem = new ListTile(
leading: new Icon(Icons.hourglass_empty),
title: new Text('Animate Slowly'),
trailing: new Checkbox(
value: timeDilation != 1.0,
onChanged: (bool value) {
onTimeDilationChanged(value ? 20.0 : 1.0);
},
),
selected: timeDilation != 1.0,
onPressed: () { onTimeDilationChanged(timeDilation != 1.0 ? 1.0 : 20.0); },
child: new Row(
children: <Widget>[
new Expanded(child: new Text('Animate Slowly')),
new Checkbox(
value: timeDilation != 1.0,
onChanged: (bool value) { onTimeDilationChanged(value ? 20.0 : 1.0); }
)
]
)
onTap: () {
onTimeDilationChanged(timeDilation != 1.0 ? 1.0 : 20.0);
},
);
final Widget sendFeedbackItem = new DrawerItem(
icon: new Icon(Icons.report),
onPressed: onSendFeedback ?? () {
final Widget sendFeedbackItem = new ListTile(
leading: new Icon(Icons.report),
title: new Text('Send feedback'),
onTap: onSendFeedback ?? () {
UrlLauncher.launch('https://github.com/flutter/flutter/issues/new');
},
child: new Text('Send feedback'),
);
final Widget aboutItem = new AboutDrawerItem(
final Widget aboutItem = new AboutListTile(
icon: const FlutterLogo(),
applicationVersion: '2016 Q3 Preview',
applicationIcon: const FlutterLogo(),
......@@ -273,36 +265,36 @@ class GalleryDrawer extends StatelessWidget {
];
if (onShowPerformanceOverlayChanged != null) {
allDrawerItems.insert(8, new DrawerItem(
icon: new Icon(Icons.assessment),
onPressed: () { onShowPerformanceOverlayChanged(!showPerformanceOverlay); },
allDrawerItems.insert(8, new ListTile(
leading: new Icon(Icons.assessment),
title: new Text('Performance Overlay'),
trailing: new Checkbox(
value: showPerformanceOverlay,
onChanged: (bool value) {
onShowPerformanceOverlayChanged(!showPerformanceOverlay);
},
),
selected: showPerformanceOverlay,
child: new Row(
children: <Widget>[
new Expanded(child: new Text('Performance Overlay')),
new Checkbox(
value: showPerformanceOverlay,
onChanged: (bool value) { onShowPerformanceOverlayChanged(!showPerformanceOverlay); }
)
]
)
onTap: () {
onShowPerformanceOverlayChanged(!showPerformanceOverlay);
},
));
}
if (onCheckerboardRasterCacheImagesChanged != null) {
allDrawerItems.insert(8, new DrawerItem(
icon: new Icon(Icons.assessment),
onPressed: () { onCheckerboardRasterCacheImagesChanged(!checkerboardRasterCacheImages); },
allDrawerItems.insert(8, new ListTile(
leading: new Icon(Icons.assessment),
title: new Text('Checkerboard Raster Cache Images'),
trailing: new Checkbox(
value: checkerboardRasterCacheImages,
onChanged: (bool value) {
onCheckerboardRasterCacheImagesChanged(!checkerboardRasterCacheImages);
},
),
selected: checkerboardRasterCacheImages,
child: new Row(
children: <Widget>[
new Expanded(child: new Text('Checkerboard Raster Cache Images')),
new Checkbox(
value: checkerboardRasterCacheImages,
onChanged: (bool value) { onCheckerboardRasterCacheImagesChanged(!checkerboardRasterCacheImages); }
)
]
)
onTap: () {
onCheckerboardRasterCacheImagesChanged(!checkerboardRasterCacheImages);
},
));
}
......
......@@ -131,7 +131,6 @@ Future<Null> runSmokeTest(WidgetTester tester) async {
await smokeDemo(tester, routeName);
tester.binding.debugAssertNoTransientCallbacks('A transient callback was still active after leaving route $routeName');
}
expect(errors, 0);
final Finder navigationMenuButton = find.byTooltip('Open navigation menu');
......@@ -150,6 +149,11 @@ Future<Null> runSmokeTest(WidgetTester tester) async {
await tester.pump();
await tester.pump(const Duration(seconds: 1)); // Wait until it's changed.
// scroll the 'Send feedback' item into view
await tester.drag(find.text('Light'), const Offset(0.0, -200.0));
await tester.pump();
await tester.pump(const Duration(seconds: 1)); // Wait until it's changed.
// send feedback
expect(hasFeedback, false);
await tester.tap(find.text('Send feedback'));
......
......@@ -124,19 +124,20 @@ class StockHomeState extends State<StockHome> {
child: new ListView(
children: <Widget>[
new DrawerHeader(child: new Center(child: new Text('Stocks'))),
new DrawerItem(
icon: new Icon(Icons.assessment),
new ListTile(
leading: new Icon(Icons.assessment),
title: new Text('Stock List'),
selected: true,
child: new Text('Stock List')
),
new DrawerItem(
icon: new Icon(Icons.account_balance),
onPressed: null,
child: new Text('Account Balance')
new ListTile(
leading: new Icon(Icons.account_balance),
title: new Text('Account Balance'),
enabled: false,
),
new DrawerItem(
icon: new Icon(Icons.dvr),
onPressed: () {
new ListTile(
leading: new Icon(Icons.dvr),
title: new Text('Dump App to Console'),
onTap: () {
try {
debugDumpApp();
debugDumpRenderTree();
......@@ -146,38 +147,43 @@ class StockHomeState extends State<StockHome> {
debugPrint('Exception while dumping app:\n$e\n$stack');
}
},
child: new Text('Dump App to Console')
),
new Divider(),
new DrawerItem(
icon: new Icon(Icons.thumb_up),
onPressed: () => _handleStockModeChange(StockMode.optimistic),
child: new Row(
children: <Widget>[
new Expanded(child: new Text('Optimistic')),
new Radio<StockMode>(value: StockMode.optimistic, groupValue: config.configuration.stockMode, onChanged: _handleStockModeChange)
]
)
new ListTile(
leading: new Icon(Icons.thumb_up),
title: new Text('Optimistic'),
trailing: new Radio<StockMode>(
value: StockMode.optimistic,
groupValue: config.configuration.stockMode,
onChanged: _handleStockModeChange
),
onTap: () {
_handleStockModeChange(StockMode.optimistic);
},
),
new DrawerItem(
icon: new Icon(Icons.thumb_down),
onPressed: () => _handleStockModeChange(StockMode.pessimistic),
child: new Row(
children: <Widget>[
new Expanded(child: new Text('Pessimistic')),
new Radio<StockMode>(value: StockMode.pessimistic, groupValue: config.configuration.stockMode, onChanged: _handleStockModeChange)
]
)
new ListTile(
leading: new Icon(Icons.thumb_down),
title: new Text('Pessimistic'),
trailing: new Radio<StockMode>(
value: StockMode.pessimistic,
groupValue: config.configuration.stockMode,
onChanged: _handleStockModeChange
),
onTap: () {
_handleStockModeChange(StockMode.pessimistic);
},
),
new Divider(),
new DrawerItem(
icon: new Icon(Icons.settings),
onPressed: _handleShowSettings,
child: new Text('Settings')),
new DrawerItem(
icon: new Icon(Icons.help),
onPressed: _handleShowAbout,
child: new Text('About'))
new ListTile(
leading: new Icon(Icons.settings),
title: new Text('Settings'),
onTap: _handleShowSettings,
),
new ListTile(
leading: new Icon(Icons.help),
title: new Text('About'),
onTap: _handleShowAbout,
),
]
)
);
......
......@@ -103,139 +103,99 @@ class StockSettingsState extends State<StockSettings> {
Widget buildSettingsPane(BuildContext context) {
final List<Widget> rows = <Widget>[
new DrawerItem(
icon: new Icon(Icons.thumb_up),
onPressed: _confirmOptimismChange,
child: new Row(
children: <Widget>[
new Expanded(child: new Text('Everything is awesome')),
new Checkbox(
value: config.configuration.stockMode == StockMode.optimistic,
onChanged: (bool value) => _confirmOptimismChange()
),
]
)
new ListTile(
leading: new Icon(Icons.thumb_up),
title: new Text('Everything is awesome'),
onTap: _confirmOptimismChange,
trailing: new Checkbox(
value: config.configuration.stockMode == StockMode.optimistic,
onChanged: (bool value) => _confirmOptimismChange(),
),
),
new DrawerItem(
icon: new Icon(Icons.backup),
onPressed: () { _handleBackupChanged(!(config.configuration.backupMode == BackupMode.enabled)); },
child: new Row(
children: <Widget>[
new Expanded(child: new Text('Back up stock list to the cloud')),
new Switch(
value: config.configuration.backupMode == BackupMode.enabled,
onChanged: _handleBackupChanged
),
]
)
new ListTile(
leading: new Icon(Icons.backup),
title: new Text('Back up stock list to the cloud'),
onTap: () { _handleBackupChanged(!(config.configuration.backupMode == BackupMode.enabled)); },
trailing: new Switch(
value: config.configuration.backupMode == BackupMode.enabled,
onChanged: _handleBackupChanged,
),
),
new DrawerItem(
icon: new Icon(Icons.picture_in_picture),
onPressed: () { _handleShowPerformanceOverlayChanged(!config.configuration.showPerformanceOverlay); },
child: new Row(
children: <Widget>[
new Expanded(child: new Text('Show rendering performance overlay')),
new Switch(
value: config.configuration.showPerformanceOverlay,
onChanged: _handleShowPerformanceOverlayChanged
),
]
)
new ListTile(
leading: new Icon(Icons.picture_in_picture),
title: new Text('Show rendering performance overlay'),
onTap: () { _handleShowPerformanceOverlayChanged(!config.configuration.showPerformanceOverlay); },
trailing: new Switch(
value: config.configuration.showPerformanceOverlay,
onChanged: _handleShowPerformanceOverlayChanged,
),
),
new DrawerItem(
icon: new Icon(Icons.accessibility),
onPressed: () { _handleShowSemanticsDebuggerChanged(!config.configuration.showSemanticsDebugger); },
child: new Row(
children: <Widget>[
new Expanded(child: new Text('Show semantics overlay')),
new Switch(
value: config.configuration.showSemanticsDebugger,
onChanged: _handleShowSemanticsDebuggerChanged
),
]
)
new ListTile(
leading: new Icon(Icons.accessibility),
title: new Text('Show semantics overlay'),
onTap: () { _handleShowSemanticsDebuggerChanged(!config.configuration.showSemanticsDebugger); },
trailing: new Switch(
value: config.configuration.showSemanticsDebugger,
onChanged: _handleShowSemanticsDebuggerChanged,
),
),
];
assert(() {
// material grid and size construction lines are only available in checked mode
rows.addAll(<Widget>[
new DrawerItem(
icon: new Icon(Icons.border_clear),
onPressed: () { _handleShowGridChanged(!config.configuration.debugShowGrid); },
child: new Row(
children: <Widget>[
new Expanded(child: new Text('Show material grid (for debugging)')),
new Switch(
value: config.configuration.debugShowGrid,
onChanged: _handleShowGridChanged
),
]
)
new ListTile(
leading: new Icon(Icons.border_clear),
title: new Text('Show material grid (for debugging)'),
onTap: () { _handleShowGridChanged(!config.configuration.debugShowGrid); },
trailing: new Switch(
value: config.configuration.debugShowGrid,
onChanged: _handleShowGridChanged,
),
),
new DrawerItem(
icon: new Icon(Icons.border_all),
onPressed: () { _handleShowSizesChanged(!config.configuration.debugShowSizes); },
child: new Row(
children: <Widget>[
new Expanded(child: new Text('Show construction lines (for debugging)')),
new Switch(
value: config.configuration.debugShowSizes,
onChanged: _handleShowSizesChanged
),
]
)
new ListTile(
leading: new Icon(Icons.border_all),
title: new Text('Show construction lines (for debugging)'),
onTap: () { _handleShowSizesChanged(!config.configuration.debugShowSizes); },
trailing: new Switch(
value: config.configuration.debugShowSizes,
onChanged: _handleShowSizesChanged,
),
),
new DrawerItem(
icon: new Icon(Icons.format_color_text),
onPressed: () { _handleShowBaselinesChanged(!config.configuration.debugShowBaselines); },
child: new Row(
children: <Widget>[
new Expanded(child: new Text('Show baselines (for debugging)')),
new Switch(
value: config.configuration.debugShowBaselines,
onChanged: _handleShowBaselinesChanged
),
]
)
new ListTile(
leading: new Icon(Icons.format_color_text),
title: new Text('Show baselines (for debugging)'),
onTap: () { _handleShowBaselinesChanged(!config.configuration.debugShowBaselines); },
trailing: new Switch(
value: config.configuration.debugShowBaselines,
onChanged: _handleShowBaselinesChanged,
),
),
new DrawerItem(
icon: new Icon(Icons.filter_none),
onPressed: () { _handleShowLayersChanged(!config.configuration.debugShowLayers); },
child: new Row(
children: <Widget>[
new Expanded(child: new Text('Show layer boundaries (for debugging)')),
new Switch(
value: config.configuration.debugShowLayers,
onChanged: _handleShowLayersChanged
),
]
)
new ListTile(
leading: new Icon(Icons.filter_none),
title: new Text('Show layer boundaries (for debugging)'),
onTap: () { _handleShowLayersChanged(!config.configuration.debugShowLayers); },
trailing: new Switch(
value: config.configuration.debugShowLayers,
onChanged: _handleShowLayersChanged,
),
),
new DrawerItem(
icon: new Icon(Icons.mouse),
onPressed: () { _handleShowPointersChanged(!config.configuration.debugShowPointers); },
child: new Row(
children: <Widget>[
new Expanded(child: new Text('Show pointer hit-testing (for debugging)')),
new Switch(
value: config.configuration.debugShowPointers,
onChanged: _handleShowPointersChanged
),
]
)
new ListTile(
leading: new Icon(Icons.mouse),
title: new Text('Show pointer hit-testing (for debugging)'),
onTap: () { _handleShowPointersChanged(!config.configuration.debugShowPointers); },
trailing: new Switch(
value: config.configuration.debugShowPointers,
onChanged: _handleShowPointersChanged,
),
),
new DrawerItem(
icon: new Icon(Icons.gradient),
onPressed: () { _handleShowRainbowChanged(!config.configuration.debugShowRainbow); },
child: new Row(
children: <Widget>[
new Expanded(child: new Text('Show repaint rainbow (for debugging)')),
new Switch(
value: config.configuration.debugShowRainbow,
onChanged: _handleShowRainbowChanged
),
]
)
new ListTile(
leading: new Icon(Icons.gradient),
title: new Text('Show repaint rainbow (for debugging)'),
onTap: () { _handleShowRainbowChanged(!config.configuration.debugShowRainbow); },
trailing: new Switch(
value: config.configuration.debugShowRainbow,
onChanged: _handleShowRainbowChanged,
),
),
]);
return true;
......
......@@ -38,12 +38,9 @@ Element findElementOfExactWidgetTypeGoingUp(Element node, Type targetType) {
final RegExp materialIconAssetNameColorExtractor = new RegExp(r'[^/]+/ic_.+_(white|black)_[0-9]+dp\.png');
void checkIconColor(WidgetTester tester, String label, Color color) {
// The icon is going to be in the same merged semantics box as the text
// regardless of how the menu item is represented, so this is a good
// way to find the menu item. I hope.
final Element semantics = findElementOfExactWidgetTypeGoingUp(tester.element(find.text(label)), MergeSemantics);
expect(semantics, isNotNull);
final Element asset = findElementOfExactWidgetTypeGoingDown(semantics, RichText);
final Element listTile = findElementOfExactWidgetTypeGoingUp(tester.element(find.text(label)), ListTile);
expect(listTile, isNotNull);
final Element asset = findElementOfExactWidgetTypeGoingDown(listTile, RichText);
final RichText richText = asset.widget;
expect(richText.text.style.color, equals(color));
}
......
......@@ -34,7 +34,6 @@ export 'src/material/dialog.dart';
export 'src/material/divider.dart';
export 'src/material/drawer.dart';
export 'src/material/drawer_header.dart';
export 'src/material/drawer_item.dart';
export 'src/material/dropdown.dart';
export 'src/material/expand_icon.dart';
export 'src/material/expansion_panel.dart';
......
......@@ -257,8 +257,8 @@ class LicenseEntryWithLineBreaks extends LicenseEntry {
/// * [showAboutDialog], which shows a Material-style dialog with information
/// about the application, including a button that shows a [LicensePage] that
/// uses this API to select licenses to show.
/// * [AboutDrawerItem], which is a widget to put in a [Drawer] which
/// automatically calls [showAboutDialog].
/// * [AboutListTile], which is a widget that can be added to a [Drawer]. When
/// tapped it calls [showAboutDialog].
class LicenseRegistry {
LicenseRegistry._();
......
......@@ -11,21 +11,21 @@ import 'package:flutter/foundation.dart';
import 'app_bar.dart';
import 'debug.dart';
import 'dialog.dart';
import 'drawer_item.dart';
import 'flat_button.dart';
import 'icon.dart';
import 'icon_theme.dart';
import 'icon_theme_data.dart';
import 'list_tile.dart';
import 'page.dart';
import 'progress_indicator.dart';
import 'scaffold.dart';
import 'scrollbar.dart';
import 'theme.dart';
/// A [DrawerItem] to show an about box.
/// A [ListTile] that shows an about box.
///
/// Place this in a [Drawer], specifying your preferred application name,
/// version, icon, and copyright in the appropriate fields.
/// This widget is often added to an app's [Drawer]. When tapped it shows
/// an about box dialog with [showAboutDialog].
///
/// The about box will include a button that shows licenses for software used by
/// the application. The licenses shown are those returned by the
......@@ -33,13 +33,13 @@ import 'theme.dart';
///
/// If your application does not have a [Drawer], you should provide an
/// affordance to call [showAboutDialog] or (at least) [showLicensePage].
class AboutDrawerItem extends StatelessWidget {
/// Creates a drawer item for showing an about box.
class AboutListTile extends StatelessWidget {
/// Creates a list tile for showing an about box.
///
/// The arguments are all optional. The application name, if omitted, will be
/// derived from the nearest [Title] widget. The version, icon, and legalese
/// values default to the empty string.
AboutDrawerItem({
AboutListTile({
Key key,
this.icon: const Icon(null),
this.child,
......@@ -109,10 +109,10 @@ class AboutDrawerItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
assert(debugCheckHasMaterial(context));
return new DrawerItem(
icon: icon,
child: child ?? new Text('About ${applicationName ?? _defaultApplicationName(context)}'),
onPressed: () {
return new ListTile(
leading: icon,
title: child ?? new Text('About ${applicationName ?? _defaultApplicationName(context)}'),
onTap: () {
showAboutDialog(
context: context,
applicationName: applicationName,
......@@ -131,7 +131,7 @@ class AboutDrawerItem extends StatelessWidget {
///
/// The arguments correspond to the properties on [AboutDialog].
///
/// If the application has a [Drawer], consider using [AboutDrawerItem] instead
/// If the application has a [Drawer], consider using [AboutListTile] instead
/// of calling this directly.
///
/// If you do not need an about box in your application, you should at least
......@@ -164,7 +164,7 @@ void showAboutDialog({
///
/// The arguments correspond to the properties on [LicensePage].
///
/// If the application has a [Drawer], consider using [AboutDrawerItem] instead
/// If the application has a [Drawer], consider using [AboutListTile] instead
/// of calling this directly.
///
/// The [AboutDialog] shown by [showAboutDialog] includes a button that calls
......@@ -196,7 +196,7 @@ void showLicensePage({
///
/// To show an [AboutDialog], use [showAboutDialog].
///
/// If the application has a [Drawer], the [AboutDrawerItem] widget can make the
/// If the application has a [Drawer], the [AboutListTile] widget can make the
/// process of showing an about dialog simpler.
///
/// The [AboutDialog] shown by [showAboutDialog] includes a button that calls
......@@ -316,7 +316,7 @@ class AboutDialog extends StatelessWidget {
///
/// To show a [LicensePage], use [showLicensePage].
///
/// The [AboutDialog] shown by [showAboutDialog] and [AboutDrawerItem] includes
/// The [AboutDialog] shown by [showAboutDialog] and [AboutListTile] includes
/// a button that calls [showLicensePage].
///
/// The licenses shown on the [LicensePage] are those returned by the
......
......@@ -92,7 +92,7 @@ class ButtonTheme extends InheritedWidget {
/// Defaults to 16.0 pixels of horizontal padding.
final EdgeInsets padding;
/// The color from the closest instance of this class that encloses the given context.
/// The closest instance of this class that encloses the given context.
///
/// Typical usage is as follows:
///
......
......@@ -5,6 +5,7 @@
import 'package:flutter/widgets.dart';
import 'colors.dart';
import 'list_tile.dart';
import 'material.dart';
// TODO(eseidel): Draw width should vary based on device size:
......@@ -30,7 +31,23 @@ const Duration _kBaseSettleDuration = const Duration(milliseconds: 246);
///
/// Drawers are typically used with the [Scaffold.drawer] property. The child of
/// the drawer is usually a [ListView] whose first child is a [DrawerHeader]
/// that displays status information about the current user.
/// that displays status information about the current user. The remaining
/// drawer children are often constructed with [ListTile]s, often concluding
/// with an [AboutListTile].
///
/// An open drawer can be closed by calling [Navigator.pop]. For example
/// a drawer item might close the drawer when tapped:
///
/// ```dart
/// new ListTile(
/// leading: new Icon(Icons.change_history),
/// title: new Text('Change history'),
/// onTap: () {
/// // change app state...
/// Navigator.pop(context); // close the drawer
/// },
/// );
/// ```
///
/// The [AppBar] automatically displays an appropriate [IconButton] to show the
/// [Drawer] when a [Drawer] is available in the [Scaffold]. The [Scaffold]
......@@ -43,9 +60,6 @@ const Duration _kBaseSettleDuration = const Duration(milliseconds: 246);
/// * [Scaffold.of], to obtain the current [ScaffoldState], which manages the
/// display and animation of the drawer.
/// * [ScaffoldState.openDrawer], which displays its [Drawer], if any.
/// * [Navigator.pop], which closes the drawer if it is open.
/// * [DrawerItem], a widget for items in drawers.
/// * [DrawerHeader], a widget for the top part of a drawer.
/// * <https://material.google.com/patterns/navigation-drawer.html>
class Drawer extends StatelessWidget {
/// Creates a material design drawer.
......@@ -233,8 +247,7 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
final ColorTween _color = new ColorTween(begin: Colors.transparent, end: Colors.black54);
final GlobalKey _gestureDetectorKey = new GlobalKey();
@override
Widget build(BuildContext context) {
Widget _buildDrawer(BuildContext context) {
if (_controller.status == AnimationStatus.dismissed) {
return new Align(
alignment: FractionalOffset.centerLeft,
......@@ -245,7 +258,7 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
behavior: HitTestBehavior.translucent,
excludeFromSemantics: true,
child: new Container(width: _kEdgeDragWidth)
)
),
);
} else {
return new GestureDetector(
......@@ -263,8 +276,8 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
decoration: new BoxDecoration(
backgroundColor: _color.evaluate(_controller)
),
child: new Container()
)
child: new Container(),
),
),
new Align(
alignment: FractionalOffset.centerLeft,
......@@ -275,14 +288,21 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
child: new Focus(
key: _drawerKey,
child: config.child
)
)
)
)
]
)
)
),
),
),
),
],
),
),
);
}
}
@override
Widget build(BuildContext context) {
return new ListTileTheme(
style: ListTileStyle.drawer,
child: _buildDrawer(context),
);
}
}
......@@ -17,14 +17,12 @@ const double _kDrawerHeaderHeight = 160.0 + 1.0; // bottom edge
/// Part of the material design [Drawer].
///
/// Requires one of its ancestors to be a [Material] widget. This condition is
/// satisfied by putting the [DrawerItem] in a [Drawer].
/// satisfied by putting the [DrawerHeader] in a [Drawer].
///
/// See also:
///
/// * [Drawer]
/// * [UserAccountsDrawerHeader], a variant of [DrawerHeader] that is
/// specialized for showing user accounts.
/// * [DrawerItem]
/// * <https://material.google.com/patterns/navigation-drawer.html>
class DrawerHeader extends StatelessWidget {
/// Creates a material design drawer header.
......
// 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/foundation.dart';
import 'package:flutter/widgets.dart';
import 'colors.dart';
import 'constants.dart';
import 'debug.dart';
import 'icon.dart';
import 'icon_theme.dart';
import 'icon_theme_data.dart';
import 'image_icon.dart';
import 'ink_well.dart';
import 'theme.dart';
/// An item in a material design drawer.
///
/// Part of the material design [Drawer].
///
/// Requires one of its ancestors to be a [Material] widget. This condition is
/// satisfied by putting the [DrawerItem] in a [Drawer].
///
/// See also:
///
/// * [Drawer]
/// * [DrawerHeader]
/// * <https://material.google.com/patterns/navigation-drawer.html>
class DrawerItem extends StatelessWidget {
/// Creates a material design drawer item.
///
/// Requires one of its ancestors to be a [Material] widget.
const DrawerItem({
Key key,
this.icon: const Icon(null),
@required this.child,
this.onPressed,
this.selected: false
}) : super(key: key);
/// The icon to display before the child widget.
///
/// The size and color of the icon is configured automatically using an
/// [IconTheme] and therefore do not need to be explicitly given in the
/// icon widget.
///
/// See [Icon], [ImageIcon].
final Widget icon;
/// The widget below this widget in the tree.
final Widget child;
/// Called when the user taps this drawer item.
///
/// If null, the drawer item is displayed as disabled.
///
/// To close the [Drawer] when an item is pressed, call [Navigator.pop].
final VoidCallback onPressed;
/// Whether this drawer item is currently selected.
///
/// The currently selected item is highlighted to distinguish it from other
/// drawer items.
final bool selected;
Color _getIconColor(ThemeData themeData) {
switch (themeData.brightness) {
case Brightness.light:
if (selected)
return themeData.primaryColor;
if (onPressed == null)
return Colors.black26;
return Colors.black45;
case Brightness.dark:
if (selected)
return themeData.accentColor;
if (onPressed == null)
return Colors.white30;
return null; // use default icon theme color unmodified
}
assert(themeData.brightness != null);
return null;
}
TextStyle _getTextStyle(ThemeData themeData) {
final TextStyle result = themeData.textTheme.body2;
if (selected) {
switch (themeData.brightness) {
case Brightness.light:
return result.copyWith(color: themeData.primaryColor);
case Brightness.dark:
return result.copyWith(color: themeData.accentColor);
}
}
return result;
}
@override
Widget build(BuildContext context) {
assert(debugCheckHasMaterial(context));
final ThemeData themeData = Theme.of(context);
final List<Widget> children = <Widget>[];
if (icon != null) {
children.add(
new Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: new IconTheme.merge(
context: context,
data: new IconThemeData(
color: _getIconColor(themeData),
size: 24.0
),
child: icon
)
)
);
}
if (child != null) {
children.add(
new Expanded(
child: new Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: new AnimatedDefaultTextStyle(
style: _getTextStyle(themeData),
duration: kThemeChangeDuration,
child: child
)
)
)
);
}
return new MergeSemantics(
child: new Container(
height: 48.0,
child: new InkWell(
onTap: onPressed,
child: new Row(children: children)
)
)
);
}
}
......@@ -9,7 +9,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('AboutDrawerItem control test', (WidgetTester tester) async {
testWidgets('AboutListTile control test', (WidgetTester tester) async {
await tester.pumpWidget(
new MaterialApp(
title: 'Pirate app',
......@@ -20,7 +20,7 @@ void main() {
drawer: new Drawer(
child: new ListView(
children: <Widget>[
new AboutDrawerItem(
new AboutListTile(
applicationVersion: '0.1.2',
applicationIcon: const FlutterLogo(),
applicationLegalese: 'I am the very model of a modern major general.',
......@@ -67,12 +67,12 @@ void main() {
testWidgets('About box logic defaults to executable name for app name', (WidgetTester tester) async {
await tester.pumpWidget(
new Material(child: new AboutDrawerItem()),
new Material(child: new AboutListTile()),
);
expect(find.text('About sky_shell'), findsOneWidget);
});
testWidgets('AboutDrawerItem control test', (WidgetTester tester) async {
testWidgets('AboutListTile control test', (WidgetTester tester) async {
final List<String> log = <String>[];
Future<Null> licenseFuture;
......
......@@ -20,9 +20,9 @@ void main() {
child: new Text('header')
)
),
new DrawerItem(
icon: new Icon(Icons.archive),
child: new Text('Archive')
new ListTile(
leading: new Icon(Icons.archive),
title: new Text('Archive')
)
]
)
......
// 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_test/flutter_test.dart';
void main() {
testWidgets('ListTile control test', (WidgetTester tester) async {
await tester.pumpWidget(new MaterialApp(
home: new Material(
child: new Center(
child: new ListTile(
leading: new Icon(Icons.thumb_up),
title: new Text('Title'),
subtitle: new Text('Subtitle'),
trailing: new Icon(Icons.info),
enabled: false,
),
),
),
));
expect(find.text('Title'), findsOneWidget);
expect(find.text('Subtitle'), findsOneWidget);
});
testWidgets('ListTile control test', (WidgetTester tester) async {
final List<String> titles = <String>[ 'first', 'second', 'third' ];
await tester.pumpWidget(new MaterialApp(
home: new Material(
child: new Builder(
builder: (BuildContext context) {
return new ListView(
children: ListTile.divideTiles(
context: context,
tiles: titles.map((String title) => new ListTile(title: new Text(title))),
).toList(),
);
},
),
),
));
expect(find.text('first'), findsOneWidget);
expect(find.text('second'), findsOneWidget);
expect(find.text('third'), findsOneWidget);
});
}
// 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_test/flutter_test.dart';
class TestIcon extends StatefulWidget {
TestIcon({ Key key }) : super(key: key);
@override
TestIconState createState() => new TestIconState();
}
class TestIconState extends State<TestIcon> {
IconThemeData iconTheme;
@override
Widget build(BuildContext context) {
iconTheme = IconTheme.of(context);
return new Icon(Icons.add);
}
}
class TestText extends StatefulWidget {
TestText(this.text, { Key key }) : super(key: key);
final String text;
@override
TestTextState createState() => new TestTextState();
}
class TestTextState extends State<TestText> {
TextStyle textStyle;
@override
Widget build(BuildContext context) {
textStyle = DefaultTextStyle.of(context).style;
return new Text(config.text);
}
}
void main() {
testWidgets('ListTile geometry', (WidgetTester tester) async {
// See https://material.io/guidelines/components/lists.html
bool hasSubtitle;
Widget buildFrame({ bool dense: false, bool isTwoLine: false, bool isThreeLine: false }) {
hasSubtitle = isTwoLine || isThreeLine;
return new MaterialApp(
home: new Material(
child: new Center(
child: new ListTile(
leading: new Text('leading'),
title: new Text('title'),
subtitle: hasSubtitle ? new Text('subtitle') : null,
trailing: new Text('trailing'),
dense: dense,
isThreeLine: isThreeLine,
),
),
),
);
}
void testChildren() {
expect(find.text('leading'), findsOneWidget);
expect(find.text('title'), findsOneWidget);
if (hasSubtitle)
expect(find.text('subtitle'), findsOneWidget);
expect(find.text('trailing'), findsOneWidget);
}
double left(String text) => tester.getTopLeft(find.text(text)).x;
double right(String text) => tester.getTopRight(find.text(text)).x;
double top(String text) => tester.getTopLeft(find.text(text)).y;
double bottom(String text) => tester.getBottomLeft(find.text(text)).y;
// 16.0 padding to the left and right of the leading and trailing widgets
void testHorizontalGeometry() {
expect(left('leading'), 16.0);
expect(left('title'), 72.0);
if (hasSubtitle)
expect(left('subtitle'), 72.0);
expect(left('title'), right('leading') + 16.0);
expect(right('trailing'), 800.0 - 16.0);
}
void testVerticalGeometry(double expectedHeight) {
expect(tester.getSize(find.byType(ListTile)), new Size(800.0, expectedHeight));
if (hasSubtitle)
expect(top('subtitle'), bottom('title'));
}
await tester.pumpWidget(buildFrame());
testChildren();
testHorizontalGeometry();
testVerticalGeometry(56.0);
await tester.pumpWidget(buildFrame(dense: true));
testChildren();
testHorizontalGeometry();
testVerticalGeometry(48.0);
await tester.pumpWidget(buildFrame(isTwoLine: true));
testChildren();
testHorizontalGeometry();
testVerticalGeometry(72.0);
await tester.pumpWidget(buildFrame(isTwoLine: true, dense: true));
testChildren();
testHorizontalGeometry();
testVerticalGeometry(60.0);
await tester.pumpWidget(buildFrame(isThreeLine: true));
testChildren();
testHorizontalGeometry();
testVerticalGeometry(88.0);
await tester.pumpWidget(buildFrame(isThreeLine: true, dense: true));
testChildren();
testHorizontalGeometry();
testVerticalGeometry(76.0);
});
testWidgets('ListTile.divideTiles', (WidgetTester tester) async {
final List<String> titles = <String>[ 'first', 'second', 'third' ];
await tester.pumpWidget(new MaterialApp(
home: new Material(
child: new Builder(
builder: (BuildContext context) {
return new ListView(
children: ListTile.divideTiles(
context: context,
tiles: titles.map((String title) => new ListTile(title: new Text(title))),
).toList(),
);
},
),
),
));
expect(find.text('first'), findsOneWidget);
expect(find.text('second'), findsOneWidget);
expect(find.text('third'), findsOneWidget);
});
testWidgets('ListTileTheme', (WidgetTester tester) async {
final Key titleKey = new UniqueKey();
final Key subtitleKey = new UniqueKey();
ThemeData theme;
Widget buildFrame({
bool enabled: true,
bool dense: false,
bool selected: false,
Color selectedColor,
Color iconColor,
Color textColor,
}) {
return new MaterialApp(
home: new Material(
child: new Center(
child: new ListTileTheme(
dense: dense,
selectedColor: selectedColor,
iconColor: iconColor,
textColor: textColor,
child: new Builder(
builder: (BuildContext context) {
theme = Theme.of(context);
return new ListTile(
enabled: enabled,
selected: selected,
leading: new TestIcon(),
title: new TestText('title', key: titleKey),
subtitle: new TestText('subtitle', key: subtitleKey),
);
}
),
),
),
),
);
}
const Color green = const Color(0xFF00FF00);
const Color red = const Color(0xFFFF0000);
Color iconColor() => tester.state<TestIconState>(find.byType(TestIcon)).iconTheme.color;
Color textColor(Key key) => tester.state<TestTextState>(find.byKey(key)).textStyle.color;
// A selected ListTile's leading and text get the primary color by default
await(tester.pumpWidget(buildFrame(selected: true)));
await(tester.pump(const Duration(milliseconds: 300))); // DefaultTextStyle changes animate
expect(iconColor(), theme.primaryColor);
expect(textColor(titleKey), theme.primaryColor);
expect(textColor(subtitleKey), theme.primaryColor);
// A selected ListTile's leading and text get the ListTileTheme's selectedColor
await(tester.pumpWidget(buildFrame(selected: true, selectedColor: green)));
await(tester.pump(const Duration(milliseconds: 300))); // DefaultTextStyle changes animate
expect(iconColor(), green);
expect(textColor(titleKey), green);
expect(textColor(subtitleKey), green);
// An unselected ListTile's leading icon gets the ListTileTheme's iconColor
// An unselected ListTile's title texts get the ListTileTheme's textColor
await(tester.pumpWidget(buildFrame(iconColor: red, textColor: green)));
await(tester.pump(const Duration(milliseconds: 300))); // DefaultTextStyle changes animate
expect(iconColor(), red);
expect(textColor(titleKey), green);
expect(textColor(subtitleKey), green);
// If the item is disabled it's rendered with the theme's disabled color.
await(tester.pumpWidget(buildFrame(enabled: false)));
await(tester.pump(const Duration(milliseconds: 300))); // DefaultTextStyle changes animate
expect(iconColor(), theme.disabledColor);
expect(textColor(titleKey), theme.disabledColor);
expect(textColor(subtitleKey), theme.disabledColor);
// If the item is disabled it's rendered with the theme's disabled color.
// Even if it's selected.
await(tester.pumpWidget(buildFrame(enabled: false, selected: true)));
await(tester.pump(const Duration(milliseconds: 300))); // DefaultTextStyle changes animate
expect(iconColor(), theme.disabledColor);
expect(textColor(titleKey), theme.disabledColor);
expect(textColor(subtitleKey), theme.disabledColor);
});
}
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