Unverified Commit 5c2259d5 authored by Hans Muller's avatar Hans Muller Committed by GitHub

Cross fade gallery UI front layer (#17064)

parent 7a0ebad0
......@@ -46,7 +46,7 @@ const String _actionText =
const String _actionCode = 'buttons_action';
class ButtonsDemo extends StatefulWidget {
static const String routeName = '/material//buttons';
static const String routeName = '/material/buttons';
@override
_ButtonsDemoState createState() => new _ButtonsDemoState();
......
......@@ -45,30 +45,10 @@ class _GalleryAppState extends State<GalleryApp> {
// 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
return new Map<String, WidgetBuilder>.fromIterable(
kAllGalleryDemos,
key: (dynamic demo) => '${demo.routeName}',
value: (dynamic demo) => demo.buildRoute,
)..addAll(
new Map<String, WidgetBuilder>.fromIterable(
kAllGalleryDemoCategories,
key: (dynamic category) => '/${category.name}',
value: (dynamic category) {
return (BuildContext context) {
return new DemosPage(
category: category,
optionsPage: new GalleryOptionsPage(
options: _options,
onOptionsChanged: _handleOptionsChanged,
onSendFeedback: widget.onSendFeedback ?? () {
launch('https://github.com/flutter/flutter/issues/new', forceSafariVC: false);
},
),
);
};
},
),
);
}
......@@ -131,7 +111,7 @@ class _GalleryAppState extends State<GalleryApp> {
options: _options,
onOptionsChanged: _handleOptionsChanged,
onSendFeedback: widget.onSendFeedback ?? () {
launch('https://github.com/flutter/flutter/issues/new');
launch('https://github.com/flutter/flutter/issues/new', forceSafariVC: false);
},
),
);
......
......@@ -115,7 +115,7 @@ class _CrossFadeTransition extends AnimatedWidget {
),
),
new IgnorePointer(
ignoring: opacity2 <1.0,
ignoring: opacity2 < 1.0,
child: new Opacity(
opacity: opacity2,
child: new Semantics(
......
......@@ -13,6 +13,7 @@ import 'demos.dart';
const String _kGalleryAssetsPackage = 'flutter_gallery_assets';
const Color _kFlutterBlue = const Color(0xFF003D75);
const double _kDemoItemHeight = 64.0;
const Duration _kFrontLayerSwitchDuration = const Duration(milliseconds: 300);
class _FlutterLogo extends StatelessWidget {
const _FlutterLogo({ Key key }) : super(key: key);
......@@ -104,6 +105,7 @@ class _CategoriesPage extends StatelessWidget {
final int columnCount = (MediaQuery.of(context).orientation == Orientation.portrait) ? 2 : 3;
return new SingleChildScrollView(
key: const PageStorageKey<String>('categories'),
child: new LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
final double columnWidth = constraints.biggest.width / columnCount.toDouble();
......@@ -130,7 +132,7 @@ class _CategoriesPage extends StatelessWidget {
child: new _CategoryItem(
category: category,
onTap: () {
Navigator.pushNamed(context, '/${category.name}');
onCategoryTap(category);
},
),
);
......@@ -213,51 +215,21 @@ class _DemoItem extends StatelessWidget {
}
}
class DemosPage extends StatelessWidget {
const DemosPage({
Key key,
this.category,
this.optionsPage,
}) : super(key: key);
class _DemosPage extends StatelessWidget {
const _DemosPage(this.category);
final GalleryDemoCategory category;
final Widget optionsPage;
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final bool isDark = theme.brightness == Brightness.dark;
return new Scaffold(
backgroundColor: isDark ? _kFlutterBlue : theme.primaryColor,
body: new SafeArea(
child: new SizedBox.expand(
child: new Backdrop(
backTitle: const Text('Options'),
backLayer: optionsPage,
frontAction: const BackButton(),
frontTitle: new Text(category.name),
frontHeading: new Container(
height: 40.0,
alignment: Alignment.bottomCenter,
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: const Divider(
color: const Color(0xFFD5D7DA),
height: 1.0
),
),
frontLayer: new Padding(
padding: const EdgeInsets.only(top: 40.0),
child: new ListView(
key: const ValueKey<String>('GalleryDemoList'), // So tests can find it.
padding: const EdgeInsets.only(top: 8.0),
children: kGalleryCategoryToDemos[category].map<Widget>((GalleryDemo demo) {
return new _DemoItem(demo: demo);
}).toList(),
),
),
),
),
return new KeyedSubtree(
key: const ValueKey<String>('GalleryDemoList'), // So the tests can find this ListView
child: new ListView(
key: new PageStorageKey<String>(category.name),
padding: const EdgeInsets.only(top: 8.0),
children: kGalleryCategoryToDemos[category].map<Widget>((GalleryDemo demo) {
return new _DemoItem(demo: demo);
}).toList(),
),
);
}
......@@ -282,6 +254,7 @@ class GalleryHome extends StatefulWidget {
class _GalleryHomeState extends State<GalleryHome> with SingleTickerProviderStateMixin {
static final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
AnimationController _controller;
GalleryDemoCategory _category;
@override
void initState() {
......@@ -312,11 +285,39 @@ class _GalleryHomeState extends State<GalleryHome> with SingleTickerProviderStat
child: new Backdrop(
backTitle: const Text('Options'),
backLayer: widget.optionsPage,
frontAction: const _FlutterLogo(),
frontTitle: const Text('Flutter gallery'),
frontAction: new AnimatedSwitcher(
duration: _kFrontLayerSwitchDuration,
child: _category == null
? const _FlutterLogo()
: new IconButton(
icon: const BackButtonIcon(),
tooltip: 'Back',
onPressed: () {
setState(() {
_category = null;
});
},
),
),
frontTitle: new AnimatedSwitcher(
duration: _kFrontLayerSwitchDuration,
child: _category == null
? const Text('Flutter gallery')
: new Text(_category.name),
),
frontHeading: new Container(height: 24.0),
frontLayer: new _CategoriesPage(
categories: kAllGalleryDemoCategories,
frontLayer: new AnimatedSwitcher(
duration: _kFrontLayerSwitchDuration,
child: _category != null
? new _DemosPage(_category)
: new _CategoriesPage(
categories: kAllGalleryDemoCategories,
onCategoryTap: (GalleryDemoCategory category) {
setState(() {
_category = category;
});
},
),
),
),
),
......
......@@ -18,7 +18,7 @@ void main() {
await tester.pump(); // see https://github.com/flutter/flutter/issues/1865
await tester.pump(); // triggers a frame
Scrollable.ensureVisible(tester.element(find.text('Material')), alignment: 0.5);
await Scrollable.ensureVisible(tester.element(find.text('Material')), alignment: 0.5);
await tester.pumpAndSettle();
await tester.tap(find.text('Material'));
await tester.pumpAndSettle();
......
......@@ -150,10 +150,11 @@ Future<Null> smokeGallery(WidgetTester tester) async {
expect(find.text(kGalleryTitle), findsOneWidget);
for (GalleryDemoCategory category in kAllGalleryDemoCategories) {
await Scrollable.ensureVisible(tester.element(find.text(category.name)), alignment: 0.5);
await tester.tap(find.text(category.name));
await tester.pumpAndSettle();
for (GalleryDemo demo in kGalleryCategoryToDemos[category]) {
Scrollable.ensureVisible(tester.element(find.text(demo.title)), alignment: 0.5);
await Scrollable.ensureVisible(tester.element(find.text(demo.title)), alignment: 0.0);
await smokeDemo(tester, demo);
tester.binding.debugAssertNoTransientCallbacks('A transient callback was still active after running $demo');
}
......
......@@ -126,12 +126,15 @@ Future<Null> runDemos(List<String> demos, FlutterDriver driver) async {
for (String demo in demos) {
final String demoAtCategory = _allDemos.firstWhere((String s) => s.startsWith(demo));
final String demoCategory = demoAtCategory.substring(demoAtCategory.indexOf('@') + 1);
print('> $demoAtCategory');
if (currentDemoCategory == null) {
await driver.tap(find.text(demoCategory));
} else if (currentDemoCategory != demoCategory) {
await driver.tap(find.byTooltip('Back'));
await driver.tap(find.text(demoCategory));
// Scroll back to the top
await driver.scroll(demoList, 0.0, 10000.0, const Duration(milliseconds: 100));
}
currentDemoCategory = demoCategory;
......@@ -150,7 +153,7 @@ Future<Null> runDemos(List<String> demos, FlutterDriver driver) async {
}
}
print('Success');
print('< Success');
}
// Return to the home screen
......
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