Add large text switching to Gallery app. (#12443)
This lets us preview widgets in the gallery using small, normal, large, and HUGE text.
Added selections to the main drawer for these options. Defaults to "normal", obviously.
diff --git a/examples/flutter_gallery/lib/demo/material/scrollable_tabs_demo.dart b/examples/flutter_gallery/lib/demo/material/scrollable_tabs_demo.dart
index dc741b6..e7c9092 100644
--- a/examples/flutter_gallery/lib/demo/material/scrollable_tabs_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/scrollable_tabs_demo.dart
@@ -22,7 +22,7 @@
new _Page(icon: Icons.android, text: 'ANDROID'),
new _Page(icon: Icons.alarm, text: 'ALARM'),
new _Page(icon: Icons.face, text: 'FACE'),
- new _Page(icon: Icons.language, text: 'LANGAUGE'),
+ new _Page(icon: Icons.language, text: 'LANGUAGE'),
];
class ScrollableTabsDemo extends StatefulWidget {
diff --git a/examples/flutter_gallery/lib/gallery/app.dart b/examples/flutter_gallery/lib/gallery/app.dart
index e5d814b..a07a707 100644
--- a/examples/flutter_gallery/lib/gallery/app.dart
+++ b/examples/flutter_gallery/lib/gallery/app.dart
@@ -12,15 +12,6 @@
import 'item.dart';
import 'updates.dart';
-final Map<String, WidgetBuilder> _kRoutes = new Map<String, WidgetBuilder>.fromIterable(
- // For a different example of how to set up an application routing table,
- // consider the Stocks example:
- // https://github.com/flutter/flutter/blob/master/examples/stocks/lib/main.dart
- kAllGalleryItems,
- key: (GalleryItem item) => item.routeName,
- value: (GalleryItem item) => item.buildRoute,
-);
-
final ThemeData _kGalleryLightTheme = new ThemeData(
brightness: Brightness.light,
primarySwatch: Colors.blue,
@@ -63,6 +54,9 @@
double _timeDilation = 1.0;
TargetPlatform _platform;
+ // A null value indicates "use system default".
+ double _textScaleFactor;
+
Timer _timeDilationTimer;
@override
@@ -128,6 +122,12 @@
}
});
},
+ textScaleFactor: _textScaleFactor,
+ onTextScaleFactorChanged: (double value) {
+ setState(() {
+ _textScaleFactor = value;
+ });
+ },
onSendFeedback: widget.onSendFeedback,
);
@@ -138,6 +138,33 @@
);
}
+ final Map<String, WidgetBuilder> _kRoutes = new Map<String,
+ WidgetBuilder>.fromIterable(
+ // For a different example of how to set up an application routing table
+ // using named routes, consider the example in the Navigator class documentation:
+ // https://docs.flutter.io/flutter/widgets/Navigator-class.html
+ kAllGalleryItems,
+ key: (GalleryItem item) => item.routeName,
+ value: (GalleryItem item) =>
+ (BuildContext context) {
+ if (_textScaleFactor != null) {
+ return new MediaQuery(
+ data: new MediaQueryData(textScaleFactor: _textScaleFactor),
+ child: item.buildRoute(context),
+ );
+ } else {
+ return item.buildRoute(context);
+ }
+ }
+ );
+
+ if (_textScaleFactor != null) {
+ home = new MediaQuery(
+ data: new MediaQueryData(textScaleFactor: _textScaleFactor),
+ child: home,
+ );
+ }
+
return new MaterialApp(
title: 'Flutter Gallery',
color: Colors.grey,
diff --git a/examples/flutter_gallery/lib/gallery/drawer.dart b/examples/flutter_gallery/lib/gallery/drawer.dart
index 992b6a7..14f2d66 100644
--- a/examples/flutter_gallery/lib/gallery/drawer.dart
+++ b/examples/flutter_gallery/lib/gallery/drawer.dart
@@ -108,6 +108,8 @@
@required this.onThemeChanged,
this.timeDilation,
@required this.onTimeDilationChanged,
+ this.textScaleFactor,
+ this.onTextScaleFactorChanged,
this.showPerformanceOverlay,
this.onShowPerformanceOverlayChanged,
this.checkerboardRasterCacheImages,
@@ -126,6 +128,9 @@
final double timeDilation;
final ValueChanged<double> onTimeDilationChanged;
+ final double textScaleFactor;
+ final ValueChanged<double> onTextScaleFactorChanged;
+
final bool showPerformanceOverlay;
final ValueChanged<bool> onShowPerformanceOverlayChanged;
@@ -183,6 +188,25 @@
selected: Theme.of(context).platform == TargetPlatform.iOS,
);
+ final List<Widget> textSizeItems = <Widget>[];
+ final Map<double, String> textSizes = <double, String>{
+ null: 'System Default',
+ 0.8: 'Small',
+ 1.0: 'Normal',
+ 1.3: 'Large',
+ 2.0: 'Huge',
+ };
+ for (double size in textSizes.keys) {
+ textSizeItems.add(new RadioListTile<double>(
+ secondary: const Icon(Icons.text_fields),
+ title: new Text(textSizes[size]),
+ value: size,
+ groupValue: textScaleFactor,
+ onChanged: onTextScaleFactorChanged,
+ selected: textScaleFactor == size,
+ ));
+ }
+
final Widget animateSlowlyItem = new CheckboxListTile(
title: const Text('Animate Slowly'),
value: timeDilation != 1.0,
@@ -214,11 +238,11 @@
children: <TextSpan>[
new TextSpan(
style: aboutTextStyle,
- text: "Flutter is an early-stage, open-source project to help "
- "developers build high-performance, high-fidelity, mobile "
- "apps for iOS and Android from a single codebase. This "
- "gallery is a preview of Flutter's many widgets, behaviors, "
- "animations, layouts, and more. Learn more about Flutter at "
+ text: 'Flutter is an early-stage, open-source project to help '
+ 'developers build high-performance, high-fidelity, mobile '
+ 'apps for iOS and Android from a single codebase. This '
+ "gallery is a preview of Flutter's many widgets, behaviors, "
+ 'animations, layouts, and more. Learn more about Flutter at '
),
new LinkTextSpan(
style: linkStyle,
@@ -226,7 +250,7 @@
),
new TextSpan(
style: aboutTextStyle,
- text: ".\n\nTo see the source code for this app, please visit the "
+ text: '.\n\nTo see the source code for this app, please visit the '
),
new LinkTextSpan(
style: linkStyle,
@@ -235,7 +259,7 @@
),
new TextSpan(
style: aboutTextStyle,
- text: "."
+ text: '.'
)
]
)
@@ -252,42 +276,58 @@
mountainViewItem,
cupertinoItem,
const Divider(),
- animateSlowlyItem,
- // index 8, optional: Performance Overlay
- sendFeedbackItem,
- aboutItem
];
- if (onShowPerformanceOverlayChanged != null) {
- allDrawerItems.insert(8, new CheckboxListTile(
- title: const Text('Performance Overlay'),
- value: showPerformanceOverlay,
- onChanged: onShowPerformanceOverlayChanged,
- secondary: const Icon(Icons.assessment),
- selected: showPerformanceOverlay,
- ));
- }
+ allDrawerItems.addAll(textSizeItems);
- if (onCheckerboardRasterCacheImagesChanged != null) {
- allDrawerItems.insert(8, new CheckboxListTile(
- title: const Text('Checkerboard Raster Cache Images'),
- value: checkerboardRasterCacheImages,
- onChanged: onCheckerboardRasterCacheImagesChanged,
- secondary: const Icon(Icons.assessment),
- selected: checkerboardRasterCacheImages,
- ));
- }
+ allDrawerItems..addAll(<Widget>[
+ const Divider(),
+ animateSlowlyItem,
+ const Divider(),
+ ]);
+ bool addedOptionalItem = false;
if (onCheckerboardOffscreenLayersChanged != null) {
- allDrawerItems.insert(8, new CheckboxListTile(
+ allDrawerItems.add(new CheckboxListTile(
title: const Text('Checkerboard Offscreen Layers'),
value: checkerboardOffscreenLayers,
onChanged: onCheckerboardOffscreenLayersChanged,
secondary: const Icon(Icons.assessment),
selected: checkerboardOffscreenLayers,
));
+ addedOptionalItem = true;
}
+ if (onCheckerboardRasterCacheImagesChanged != null) {
+ allDrawerItems.add(new CheckboxListTile(
+ title: const Text('Checkerboard Raster Cache Images'),
+ value: checkerboardRasterCacheImages,
+ onChanged: onCheckerboardRasterCacheImagesChanged,
+ secondary: const Icon(Icons.assessment),
+ selected: checkerboardRasterCacheImages,
+ ));
+ addedOptionalItem = true;
+ }
+
+ if (onShowPerformanceOverlayChanged != null) {
+ allDrawerItems.add(new CheckboxListTile(
+ title: const Text('Performance Overlay'),
+ value: showPerformanceOverlay,
+ onChanged: onShowPerformanceOverlayChanged,
+ secondary: const Icon(Icons.assessment),
+ selected: showPerformanceOverlay,
+ ));
+ addedOptionalItem = true;
+ }
+
+ if (addedOptionalItem)
+ allDrawerItems.add(const Divider());
+
+ allDrawerItems.addAll(<Widget>[
+ sendFeedbackItem,
+ aboutItem,
+ ]);
+
return new Drawer(child: new ListView(primary: false, children: allDrawerItems));
}
}
diff --git a/examples/flutter_gallery/lib/gallery/home.dart b/examples/flutter_gallery/lib/gallery/home.dart
index 2356cd3..70e949f 100644
--- a/examples/flutter_gallery/lib/gallery/home.dart
+++ b/examples/flutter_gallery/lib/gallery/home.dart
@@ -68,6 +68,8 @@
@required this.onThemeChanged,
this.timeDilation,
@required this.onTimeDilationChanged,
+ this.textScaleFactor,
+ this.onTextScaleFactorChanged,
this.showPerformanceOverlay,
this.onShowPerformanceOverlayChanged,
this.checkerboardRasterCacheImages,
@@ -86,6 +88,9 @@
final double timeDilation;
final ValueChanged<double> onTimeDilationChanged;
+ final double textScaleFactor;
+ final ValueChanged<double> onTextScaleFactorChanged;
+
final bool showPerformanceOverlay;
final ValueChanged<bool> onShowPerformanceOverlayChanged;
@@ -159,6 +164,8 @@
onThemeChanged: widget.onThemeChanged,
timeDilation: widget.timeDilation,
onTimeDilationChanged: widget.onTimeDilationChanged,
+ textScaleFactor: widget.textScaleFactor,
+ onTextScaleFactorChanged: widget.onTextScaleFactorChanged,
showPerformanceOverlay: widget.showPerformanceOverlay,
onShowPerformanceOverlayChanged: widget.onShowPerformanceOverlayChanged,
checkerboardRasterCacheImages: widget.checkerboardRasterCacheImages,
diff --git a/examples/flutter_gallery/test/drawer_test.dart b/examples/flutter_gallery/test/drawer_test.dart
new file mode 100644
index 0000000..3eb42bd
--- /dev/null
+++ b/examples/flutter_gallery/test/drawer_test.dart
@@ -0,0 +1,100 @@
+// Copyright 2017 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/scheduler.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:flutter_gallery/gallery/app.dart';
+
+void main() {
+ final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized();
+ if (binding is LiveTestWidgetsFlutterBinding)
+ binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.fullyLive;
+
+ testWidgets('Flutter Gallery drawer item test', (WidgetTester tester) async {
+ bool hasFeedback = false;
+ void mockOnSendFeedback() {
+ hasFeedback = true;
+ }
+
+ await tester.pumpWidget(new GalleryApp(onSendFeedback: mockOnSendFeedback));
+ await tester.pump(); // see https://github.com/flutter/flutter/issues/1865
+ await tester.pump(); // triggers a frame
+
+ final Finder finder = find.byWidgetPredicate((Widget widget) {
+ return widget is Tooltip && widget.message == 'Open navigation menu';
+ });
+ expect(finder, findsOneWidget);
+
+ // Open drawer
+ await tester.tap(finder);
+ await tester.pump(); // start animation
+ await tester.pump(const Duration(seconds: 1)); // end animation
+
+ MaterialApp app = find.byType(MaterialApp).evaluate().first.widget;
+ expect(app.theme.brightness, equals(Brightness.light));
+
+ // Change theme
+ await tester.tap(find.text('Dark'));
+ await tester.pump(); // start animation
+ await tester.pump(const Duration(seconds: 1)); // end animation
+ app = find.byType(MaterialApp).evaluate().first.widget;
+ expect(app.theme.brightness, equals(Brightness.dark));
+ expect(app.theme.platform, equals(TargetPlatform.android));
+
+ // Change platform
+ await tester.tap(find.text('iOS'));
+ await tester.pump(); // start animation
+ await tester.pump(const Duration(seconds: 1)); // end animation
+ app = find.byType(MaterialApp).evaluate().first.widget;
+ expect(app.theme.platform, equals(TargetPlatform.iOS));
+
+ // Verify the font scale.
+ final Size origTextSize = tester.getSize(find.text("Small"));
+ expect(origTextSize, equals(const Size(176.0, 14.0)));
+
+ // Switch font scale.
+ await tester.tap(find.text('Small'));
+ await tester.pump();
+ await tester.pump(const Duration(seconds: 1)); // Wait until it's changed.
+ final Size textSize = tester.getSize(find.text("Small"));
+ expect(textSize, equals(const Size(176.0, 11.0)));
+
+ // Set font scale back to default.
+ await tester.tap(find.text('System Default'));
+ await tester.pump();
+ await tester.pump(const Duration(seconds: 1)); // Wait until it's changed.
+ final Size newTextSize = tester.getSize(find.text("Small"));
+ expect(newTextSize, equals(origTextSize));
+
+ // Scroll to the bottom of the menu.
+ await tester.drag(find.text('Small'), const Offset(0.0, -450.0));
+ await tester.pump();
+ await tester.pump(const Duration(seconds: 1)); // Wait until it's changed.
+
+ // Test slow animations.
+ expect(timeDilation, equals(1.0));
+ await tester.tap(find.text('Animate Slowly'));
+ await tester.pump();
+ await tester.pump(const Duration(seconds: 1)); // Wait until it's changed.
+ expect(timeDilation, greaterThan(1.0));
+
+ // Put back time dilation (so as not to throw off tests after this one).
+ await tester.tap(find.text('Animate Slowly'));
+ await tester.pump();
+ await tester.pump(const Duration(seconds: 1)); // Wait until it's changed.
+ expect(timeDilation, equals(1.0));
+
+ // Send feedback.
+ expect(hasFeedback, false);
+ await tester.tap(find.text('Send feedback'));
+ await tester.pump();
+ expect(hasFeedback, true);
+
+ // Close drawer
+ await tester.tap(find.byType(DrawerController));
+ await tester.pump(); // start animation
+ await tester.pump(const Duration(seconds: 1)); // end animation
+ });
+}
diff --git a/examples/flutter_gallery/test/smoke_test.dart b/examples/flutter_gallery/test/smoke_test.dart
index 26f6965..197885b 100644
--- a/examples/flutter_gallery/test/smoke_test.dart
+++ b/examples/flutter_gallery/test/smoke_test.dart
@@ -139,22 +139,31 @@
await tester.pump(); // Start opening drawer.
await tester.pump(const Duration(seconds: 1)); // Wait until it's really opened.
- // switch theme
+ // Switch theme.
await tester.tap(find.text('Dark'));
await tester.pump();
await tester.pump(const Duration(seconds: 1)); // Wait until it's changed.
- // switch theme
+ // Switch theme.
await tester.tap(find.text('Light'));
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));
+ // Switch font scale.
+ await tester.tap(find.text('Small'));
+ await tester.pump();
+ await tester.pump(const Duration(seconds: 1)); // Wait until it's changed.
+ // Switch font scale back to default.
+ await tester.tap(find.text('System Default'));
await tester.pump();
await tester.pump(const Duration(seconds: 1)); // Wait until it's changed.
- // send feedback
+ // Scroll the 'Send feedback' item into view.
+ await tester.drag(find.text('Small'), const Offset(0.0, -450.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'));
await tester.pump();