mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00

* Fix position of CupertinoContextMenu within Transform.scale (#97896) * Fix after rebase
816 lines
29 KiB
Dart
816 lines
29 KiB
Dart
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// This file is run as part of a reduced test set in CI on Mac and Windows
|
|
// machines.
|
|
@Tags(<String>['reduced-test-set'])
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
import '../widgets/semantics_tester.dart';
|
|
|
|
void main() {
|
|
testWidgets('FlexibleSpaceBar centers title on iOS', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: ThemeData(platform: TargetPlatform.android),
|
|
home: Scaffold(
|
|
appBar: AppBar(
|
|
flexibleSpace: const FlexibleSpaceBar(
|
|
title: Text('X'),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Finder title = find.text('X');
|
|
Offset center = tester.getCenter(title);
|
|
Size size = tester.getSize(title);
|
|
expect(center.dx, lessThan(400.0 - size.width / 2.0));
|
|
|
|
for (final TargetPlatform platform in <TargetPlatform>[ TargetPlatform.iOS, TargetPlatform.macOS ]) {
|
|
// Clear the widget tree to avoid animating between platforms.
|
|
await tester.pumpWidget(Container(key: UniqueKey()));
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: ThemeData(platform: platform),
|
|
home: Scaffold(
|
|
appBar: AppBar(
|
|
flexibleSpace: const FlexibleSpaceBar(
|
|
title: Text('X'),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
center = tester.getCenter(title);
|
|
size = tester.getSize(title);
|
|
expect(center.dx, greaterThan(400.0 - size.width / 2.0));
|
|
expect(center.dx, lessThan(400.0 + size.width / 2.0));
|
|
}
|
|
});
|
|
|
|
testWidgets('FlexibleSpaceBarSettings provides settings to a FlexibleSpaceBar', (WidgetTester tester) async {
|
|
const double minExtent = 100.0;
|
|
const double initExtent = 200.0;
|
|
const double maxExtent = 300.0;
|
|
const double alpha = 0.5;
|
|
|
|
final FlexibleSpaceBarSettings customSettings = FlexibleSpaceBar.createSettings(
|
|
currentExtent: initExtent,
|
|
minExtent: minExtent,
|
|
maxExtent: maxExtent,
|
|
toolbarOpacity: alpha,
|
|
child: AppBar(
|
|
flexibleSpace: const FlexibleSpaceBar(
|
|
title: Text('title'),
|
|
background: Text('X2'),
|
|
collapseMode: CollapseMode.pin,
|
|
),
|
|
),
|
|
) as FlexibleSpaceBarSettings;
|
|
|
|
const Key dragTarget = Key('orange box');
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(
|
|
body: CustomScrollView(
|
|
key: dragTarget,
|
|
primary: true,
|
|
slivers: <Widget>[
|
|
SliverPersistentHeader(
|
|
floating: true,
|
|
pinned: true,
|
|
delegate: TestDelegate(settings: customSettings),
|
|
),
|
|
SliverToBoxAdapter(
|
|
child: Container(
|
|
height: 1200.0,
|
|
color: Colors.orange[400],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
final RenderBox clipRect = tester.renderObject(find.byType(ClipRect).first);
|
|
final Transform transform = tester.firstWidget(
|
|
find.descendant(
|
|
of: find.byType(FlexibleSpaceBar),
|
|
matching: find.byType(Transform),
|
|
),
|
|
);
|
|
|
|
// The current (200) is half way between the min (100) and max (300) and the
|
|
// lerp values used to calculate the scale are 1 and 1.5, so we check for 1.25.
|
|
expect(transform.transform.getMaxScaleOnAxis(), 1.25);
|
|
|
|
// The space bar rect always starts fully expanded.
|
|
expect(clipRect.size.height, maxExtent);
|
|
|
|
final Element actionTextBox = tester.element(find.text('title'));
|
|
final Text textWidget = actionTextBox.widget as Text;
|
|
final DefaultTextStyle defaultTextStyle = DefaultTextStyle.of(actionTextBox);
|
|
|
|
final TextStyle effectiveStyle = defaultTextStyle.style.merge(textWidget.style);
|
|
expect(effectiveStyle.color?.alpha, 128); // Which is alpha of .5
|
|
|
|
// We drag up to fully collapse the space bar.
|
|
await tester.drag(find.byKey(dragTarget), const Offset(0, -400.0));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(clipRect.size.height, minExtent);
|
|
});
|
|
|
|
testWidgets('FlexibleSpaceBar.background is visible when using height other than kToolbarHeight', (WidgetTester tester) async {
|
|
// Regression test for https://github.com/flutter/flutter/issues/80451
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(
|
|
appBar: AppBar(
|
|
toolbarHeight: 300,
|
|
flexibleSpace: const FlexibleSpaceBar(
|
|
title: Text('Title'),
|
|
background: Text('Background'),
|
|
collapseMode: CollapseMode.pin,
|
|
),
|
|
),
|
|
body: CustomScrollView(
|
|
primary: true,
|
|
slivers: <Widget>[
|
|
SliverToBoxAdapter(
|
|
child: Container(
|
|
height: 1200.0,
|
|
color: Colors.orange[400],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Opacity backgroundOpacity = tester.firstWidget(find.byType(Opacity));
|
|
expect(backgroundOpacity.opacity, 1.0);
|
|
});
|
|
|
|
testWidgets('Collapsed FlexibleSpaceBar has correct semantics', (WidgetTester tester) async {
|
|
final SemanticsTester semantics = SemanticsTester(tester);
|
|
const double expandedHeight = 200;
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(
|
|
body: CustomScrollView(
|
|
slivers: <Widget>[
|
|
const SliverAppBar(
|
|
pinned: true,
|
|
expandedHeight: expandedHeight,
|
|
title: Text('Title'),
|
|
flexibleSpace: FlexibleSpaceBar(
|
|
background: Text('Expanded title'),
|
|
),
|
|
),
|
|
SliverList(
|
|
delegate: SliverChildListDelegate(
|
|
<Widget>[
|
|
for (int i = 0; i < 50; i++)
|
|
SizedBox(
|
|
height: 200,
|
|
child: Center(child: Text('Item $i')),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
TestSemantics expectedSemantics = TestSemantics.root(
|
|
children: <TestSemantics>[
|
|
TestSemantics.rootChild(
|
|
id: 1,
|
|
rect: TestSemantics.fullScreen,
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
id: 2,
|
|
rect: TestSemantics.fullScreen,
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
id: 3,
|
|
rect: TestSemantics.fullScreen,
|
|
flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
id: 4,
|
|
rect: TestSemantics.fullScreen,
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
id: 9,
|
|
rect: const Rect.fromLTRB(0.0, 0.0, 800.0, expandedHeight),
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
id: 12,
|
|
rect: const Rect.fromLTRB(0.0, 0.0, 800.0, 200.0),
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
id: 13,
|
|
rect: const Rect.fromLTRB(0.0, 0.0, 100.0, 20.0),
|
|
flags: <SemanticsFlag>[
|
|
SemanticsFlag.isHeader,
|
|
SemanticsFlag.namesRoute,
|
|
],
|
|
label: 'Title',
|
|
textDirection: TextDirection.ltr,
|
|
),
|
|
],
|
|
),
|
|
TestSemantics(
|
|
id: 10,
|
|
rect: const Rect.fromLTRB(0.0, 0.0, 800.0, 200.0),
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
id: 11,
|
|
rect: const Rect.fromLTRB(0.0, 0.0, 800.0, expandedHeight),
|
|
label: 'Expanded title',
|
|
textDirection: TextDirection.ltr,
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
TestSemantics(
|
|
id: 14,
|
|
flags: <SemanticsFlag>[SemanticsFlag.hasImplicitScrolling],
|
|
rect: TestSemantics.fullScreen,
|
|
actions: <SemanticsAction>[SemanticsAction.scrollUp],
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
id: 5,
|
|
rect: const Rect.fromLTRB(0.0, 0.0, 800.0, 200.0),
|
|
label: 'Item 0',
|
|
textDirection: TextDirection.ltr,
|
|
),
|
|
TestSemantics(
|
|
id: 6,
|
|
rect: const Rect.fromLTRB(0.0, 0.0, 800.0, 200.0),
|
|
label: 'Item 1',
|
|
textDirection: TextDirection.ltr,
|
|
),
|
|
TestSemantics(
|
|
id: 7,
|
|
rect: const Rect.fromLTRB(0.0, 0.0, 800.0, 200.0),
|
|
flags: <SemanticsFlag>[SemanticsFlag.isHidden],
|
|
label: 'Item 2',
|
|
textDirection: TextDirection.ltr,
|
|
),
|
|
TestSemantics(
|
|
id: 8,
|
|
rect: const Rect.fromLTRB(0.0, 0.0, 800.0, 50.0),
|
|
flags: <SemanticsFlag>[SemanticsFlag.isHidden],
|
|
label: 'Item 3',
|
|
textDirection: TextDirection.ltr,
|
|
),
|
|
|
|
],
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
],
|
|
);
|
|
|
|
expect(semantics, hasSemantics(expectedSemantics, ignoreTransform: true));
|
|
|
|
// We drag up to fully collapse the space bar.
|
|
await tester.drag(find.text('Item 1'), const Offset(0, -600.0));
|
|
await tester.pumpAndSettle();
|
|
|
|
expectedSemantics = TestSemantics.root(
|
|
children: <TestSemantics>[
|
|
TestSemantics.rootChild(
|
|
id: 1,
|
|
rect: TestSemantics.fullScreen,
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
id: 2,
|
|
rect: TestSemantics.fullScreen,
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
id: 3,
|
|
rect: TestSemantics.fullScreen,
|
|
flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
id: 4,
|
|
rect: TestSemantics.fullScreen,
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
id: 9,
|
|
// The app bar is collapsed.
|
|
rect: const Rect.fromLTRB(0.0, 0.0, 800.0, 56.0),
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
id: 12,
|
|
rect: const Rect.fromLTRB(0.0, 0.0, 800.0, 56.0),
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
id: 13,
|
|
rect: const Rect.fromLTRB(0.0, 0.0, 100.0, 20.0),
|
|
flags: <SemanticsFlag>[
|
|
SemanticsFlag.isHeader,
|
|
SemanticsFlag.namesRoute,
|
|
],
|
|
label: 'Title',
|
|
textDirection: TextDirection.ltr,
|
|
),
|
|
],
|
|
),
|
|
// The flexible space bar still persists in the
|
|
// semantic tree even if it is collapsed.
|
|
TestSemantics(
|
|
id: 10,
|
|
rect: const Rect.fromLTRB(0.0, 0.0, 800.0, 56.0),
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
id: 11,
|
|
rect: const Rect.fromLTRB(0.0, 36.0, 800.0, 92.0),
|
|
label: 'Expanded title',
|
|
textDirection: TextDirection.ltr,
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
TestSemantics(
|
|
id: 14,
|
|
flags: <SemanticsFlag>[SemanticsFlag.hasImplicitScrolling],
|
|
rect: TestSemantics.fullScreen,
|
|
actions: <SemanticsAction>[SemanticsAction.scrollUp, SemanticsAction.scrollDown],
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
id: 5,
|
|
rect: const Rect.fromLTRB(0.0, 150.0, 800.0, 200.0),
|
|
flags: <SemanticsFlag>[SemanticsFlag.isHidden],
|
|
label: 'Item 0',
|
|
textDirection: TextDirection.ltr,
|
|
),
|
|
TestSemantics(
|
|
id: 6,
|
|
rect: const Rect.fromLTRB(0.0, 0.0, 800.0, 200.0),
|
|
flags: <SemanticsFlag>[SemanticsFlag.isHidden],
|
|
label: 'Item 1',
|
|
textDirection: TextDirection.ltr,
|
|
),
|
|
TestSemantics(
|
|
id: 7,
|
|
rect: const Rect.fromLTRB(0.0, 56.0, 800.0, 200.0),
|
|
label: 'Item 2',
|
|
textDirection: TextDirection.ltr,
|
|
),
|
|
TestSemantics(
|
|
id: 8,
|
|
rect: const Rect.fromLTRB(0.0, 0.0, 800.0, 200.0),
|
|
label: 'Item 3',
|
|
textDirection: TextDirection.ltr,
|
|
),
|
|
TestSemantics(
|
|
id: 15,
|
|
rect: const Rect.fromLTRB(0.0, 0.0, 800.0, 200.0),
|
|
label: 'Item 4',
|
|
textDirection: TextDirection.ltr,
|
|
),
|
|
TestSemantics(
|
|
id: 16,
|
|
rect: const Rect.fromLTRB(0.0, 0.0, 800.0, 200.0),
|
|
flags: <SemanticsFlag>[SemanticsFlag.isHidden],
|
|
label: 'Item 5',
|
|
textDirection: TextDirection.ltr,
|
|
),
|
|
TestSemantics(
|
|
id: 17,
|
|
rect: const Rect.fromLTRB(0.0, 0.0, 800.0, 50.0),
|
|
flags: <SemanticsFlag>[SemanticsFlag.isHidden],
|
|
label: 'Item 6',
|
|
textDirection: TextDirection.ltr,
|
|
),
|
|
|
|
|
|
],
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
],
|
|
);
|
|
|
|
expect(semantics, hasSemantics(expectedSemantics, ignoreTransform: true));
|
|
|
|
semantics.dispose();
|
|
});
|
|
|
|
// This is a regression test for https://github.com/flutter/flutter/issues/14227
|
|
testWidgets('FlexibleSpaceBar sets width constraints for the title', (WidgetTester tester) async {
|
|
const double titleFontSize = 20.0;
|
|
const double height = 300.0;
|
|
late double width;
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(
|
|
body: Builder(
|
|
builder: (BuildContext context) {
|
|
width = MediaQuery.of(context).size.width;
|
|
return CustomScrollView(
|
|
slivers: <Widget>[
|
|
SliverAppBar(
|
|
expandedHeight: height,
|
|
pinned: true,
|
|
stretch: true,
|
|
flexibleSpace: FlexibleSpaceBar(
|
|
titlePadding: EdgeInsets.zero,
|
|
title: Text(
|
|
'X' * 2000,
|
|
maxLines: 1,
|
|
overflow: TextOverflow.ellipsis,
|
|
style: const TextStyle(fontSize: titleFontSize),
|
|
),
|
|
centerTitle: false,
|
|
),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
// The title is scaled and transformed to be 1.5 times bigger, when the
|
|
// FlexibleSpaceBar is fully expanded, thus we expect the width to be
|
|
// 1.5 times smaller than the full width. The height of the text is the same
|
|
// as the font size, with 10 dps bottom margin.
|
|
expect(
|
|
tester.getRect(find.byType(Text)),
|
|
Rect.fromLTRB(
|
|
0,
|
|
height - titleFontSize - 10,
|
|
(width / 1.5).floorToDouble() * 1.5,
|
|
height,
|
|
),
|
|
);
|
|
});
|
|
|
|
testWidgets('FlexibleSpaceBar sets constraints for the title - override expandedTitleScale', (WidgetTester tester) async {
|
|
const double titleFontSize = 20.0;
|
|
const double height = 300.0;
|
|
const double expandedTitleScale = 3.0;
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(
|
|
body: CustomScrollView(
|
|
slivers: <Widget>[
|
|
SliverAppBar(
|
|
expandedHeight: height,
|
|
pinned: true,
|
|
stretch: true,
|
|
flexibleSpace: FlexibleSpaceBar(
|
|
expandedTitleScale: expandedTitleScale,
|
|
titlePadding: EdgeInsets.zero,
|
|
title: Text(
|
|
'X' * 41,
|
|
maxLines: 1,
|
|
overflow: TextOverflow.ellipsis,
|
|
style: const TextStyle(fontSize: titleFontSize,),
|
|
),
|
|
centerTitle: false,
|
|
),
|
|
),
|
|
SliverList(
|
|
delegate: SliverChildListDelegate(
|
|
<Widget>[
|
|
for (int i = 0; i < 3; i++)
|
|
SizedBox(
|
|
height: 200.0,
|
|
child: Center(child: Text('Item $i')),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
// We drag up to fully collapse the space bar.
|
|
await tester.drag(find.text('Item 0'), const Offset(0, -600.0));
|
|
await tester.pumpAndSettle();
|
|
|
|
final Finder title = find.byType(Text).first;
|
|
final double collapsedWidth = tester.getRect(title).width;
|
|
|
|
// We drag down to fully expand the space bar.
|
|
await tester.drag(find.text('Item 2'), const Offset(0, 600.0));
|
|
await tester.pumpAndSettle();
|
|
|
|
// The title is shifted by this margin to maintain the position of the
|
|
// bottom edge.
|
|
const double bottomMargin = titleFontSize * (expandedTitleScale - 1);
|
|
|
|
// The title is scaled and transformed to be 3 times bigger, when the
|
|
// FlexibleSpaceBar is fully expanded, thus we expect the width to be
|
|
// 3 times smaller than the full width. The height of the text is the same
|
|
// as the font size, with 40 dps bottom margin to maintain its bottom position.
|
|
expect(
|
|
tester.getRect(title),
|
|
Rect.fromLTRB(
|
|
0,
|
|
height - titleFontSize - bottomMargin,
|
|
(collapsedWidth / 3).floorToDouble() * 3,
|
|
height,
|
|
),
|
|
);
|
|
});
|
|
|
|
testWidgets('FlexibleSpaceBar scaled title', (WidgetTester tester) async {
|
|
const double titleFontSize = 20.0;
|
|
const double height = 300.0;
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(
|
|
body: CustomScrollView(
|
|
slivers: <Widget>[
|
|
const SliverAppBar(
|
|
expandedHeight: height,
|
|
pinned: true,
|
|
stretch: true,
|
|
flexibleSpace: RepaintBoundary(
|
|
child: FlexibleSpaceBar(
|
|
title: Text(
|
|
'X',
|
|
style: TextStyle(fontSize: titleFontSize,),
|
|
),
|
|
centerTitle: false,
|
|
),
|
|
),
|
|
),
|
|
SliverList(
|
|
delegate: SliverChildListDelegate(
|
|
<Widget>[
|
|
for (int i = 0; i < 3; i += 1)
|
|
SizedBox(
|
|
height: 200.0,
|
|
child: Center(child: Text('Item $i')),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
// We drag up to fully collapse the space bar.
|
|
await tester.drag(find.text('Item 0'), const Offset(0, -600.0));
|
|
await tester.pumpAndSettle();
|
|
|
|
final Finder flexibleSpaceBar = find.ancestor(of: find.byType(FlexibleSpaceBar), matching: find.byType(RepaintBoundary).first);
|
|
await expectLater(
|
|
flexibleSpaceBar,
|
|
matchesGoldenFile('flexible_space_bar.expanded_title_scale_default.collapsed.png')
|
|
);
|
|
|
|
// We drag down to fully expand the space bar.
|
|
await tester.drag(find.text('Item 2'), const Offset(0, 600.0));
|
|
await tester.pumpAndSettle();
|
|
|
|
await expectLater(
|
|
flexibleSpaceBar,
|
|
matchesGoldenFile('flexible_space_bar.expanded_title_scale_default.expanded.png')
|
|
);
|
|
});
|
|
|
|
testWidgets('FlexibleSpaceBar scaled title - override expandedTitleScale', (WidgetTester tester) async {
|
|
const double titleFontSize = 20.0;
|
|
const double height = 300.0;
|
|
const double expandedTitleScale = 3.0;
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(
|
|
body: CustomScrollView(
|
|
slivers: <Widget>[
|
|
const SliverAppBar(
|
|
expandedHeight: height,
|
|
pinned: true,
|
|
stretch: true,
|
|
flexibleSpace: RepaintBoundary(
|
|
child: FlexibleSpaceBar(
|
|
title: Text(
|
|
'X',
|
|
style: TextStyle(fontSize: titleFontSize,),
|
|
),
|
|
centerTitle: false,
|
|
expandedTitleScale: expandedTitleScale,
|
|
),
|
|
),
|
|
),
|
|
SliverList(
|
|
delegate: SliverChildListDelegate(
|
|
<Widget>[
|
|
for (int i = 0; i < 3; i += 1)
|
|
SizedBox(
|
|
height: 200.0,
|
|
child: Center(child: Text('Item $i')),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
// We drag up to fully collapse the space bar.
|
|
await tester.drag(find.text('Item 0'), const Offset(0, -600.0));
|
|
await tester.pumpAndSettle();
|
|
|
|
final Finder flexibleSpaceBar = find.ancestor(of: find.byType(FlexibleSpaceBar), matching: find.byType(RepaintBoundary).first);
|
|
// This should match the default behavior
|
|
await expectLater(
|
|
flexibleSpaceBar,
|
|
matchesGoldenFile('flexible_space_bar.expanded_title_scale_default.collapsed.png')
|
|
);
|
|
|
|
// We drag down to fully expand the space bar.
|
|
await tester.drag(find.text('Item 2'), const Offset(0, 600.0));
|
|
await tester.pumpAndSettle();
|
|
|
|
await expectLater(
|
|
flexibleSpaceBar,
|
|
matchesGoldenFile('flexible_space_bar.expanded_title_scale_override.expanded.png')
|
|
);
|
|
});
|
|
|
|
testWidgets('FlexibleSpaceBar test titlePadding defaults', (WidgetTester tester) async {
|
|
Widget buildFrame(TargetPlatform platform, bool? centerTitle) {
|
|
return MaterialApp(
|
|
theme: ThemeData(platform: platform),
|
|
home: Scaffold(
|
|
appBar: AppBar(
|
|
flexibleSpace: FlexibleSpaceBar(
|
|
centerTitle: centerTitle,
|
|
title: const Text('X'),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
final Finder title = find.text('X');
|
|
final Finder flexibleSpaceBar = find.byType(FlexibleSpaceBar);
|
|
Offset getTitleBottomLeft() {
|
|
return Offset(
|
|
tester.getTopLeft(title).dx,
|
|
tester.getBottomRight(flexibleSpaceBar).dy - tester.getBottomRight(title).dy,
|
|
);
|
|
}
|
|
|
|
await tester.pumpWidget(buildFrame(TargetPlatform.android, null));
|
|
expect(getTitleBottomLeft(), const Offset(72.0, 16.0));
|
|
|
|
await tester.pumpWidget(buildFrame(TargetPlatform.android, true));
|
|
expect(getTitleBottomLeft(), const Offset(390.0, 16.0));
|
|
|
|
// Clear the widget tree to avoid animating between Android and iOS.
|
|
await tester.pumpWidget(Container(key: UniqueKey()));
|
|
|
|
await tester.pumpWidget(buildFrame(TargetPlatform.iOS, null));
|
|
expect(getTitleBottomLeft(), const Offset(390.0, 16.0));
|
|
|
|
await tester.pumpWidget(buildFrame(TargetPlatform.iOS, false));
|
|
expect(getTitleBottomLeft(), const Offset(72.0, 16.0));
|
|
|
|
// Clear the widget tree to avoid animating between iOS and macOS.
|
|
await tester.pumpWidget(Container(key: UniqueKey()));
|
|
|
|
await tester.pumpWidget(buildFrame(TargetPlatform.macOS, null));
|
|
expect(getTitleBottomLeft(), const Offset(390.0, 16.0));
|
|
|
|
await tester.pumpWidget(buildFrame(TargetPlatform.macOS, false));
|
|
expect(getTitleBottomLeft(), const Offset(72.0, 16.0));
|
|
|
|
});
|
|
|
|
testWidgets('FlexibleSpaceBar test titlePadding override', (WidgetTester tester) async {
|
|
Widget buildFrame(TargetPlatform platform, bool? centerTitle) {
|
|
return MaterialApp(
|
|
theme: ThemeData(platform: platform),
|
|
home: Scaffold(
|
|
appBar: AppBar(
|
|
flexibleSpace: FlexibleSpaceBar(
|
|
titlePadding: EdgeInsets.zero,
|
|
centerTitle: centerTitle,
|
|
title: const Text('X'),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
final Finder title = find.text('X');
|
|
final Finder flexibleSpaceBar = find.byType(FlexibleSpaceBar);
|
|
Offset getTitleBottomLeft() {
|
|
return Offset(
|
|
tester.getTopLeft(title).dx,
|
|
tester.getBottomRight(flexibleSpaceBar).dy - tester.getBottomRight(title).dy,
|
|
);
|
|
}
|
|
|
|
await tester.pumpWidget(buildFrame(TargetPlatform.android, null));
|
|
expect(getTitleBottomLeft(), Offset.zero);
|
|
|
|
await tester.pumpWidget(buildFrame(TargetPlatform.android, true));
|
|
expect(getTitleBottomLeft(), const Offset(390.0, 0.0));
|
|
|
|
// Clear the widget tree to avoid animating between platforms.
|
|
await tester.pumpWidget(Container(key: UniqueKey()));
|
|
|
|
await tester.pumpWidget(buildFrame(TargetPlatform.iOS, null));
|
|
expect(getTitleBottomLeft(), const Offset(390.0, 0.0));
|
|
|
|
await tester.pumpWidget(buildFrame(TargetPlatform.iOS, false));
|
|
expect(getTitleBottomLeft(), Offset.zero);
|
|
|
|
// Clear the widget tree to avoid animating between platforms.
|
|
await tester.pumpWidget(Container(key: UniqueKey()));
|
|
|
|
await tester.pumpWidget(buildFrame(TargetPlatform.macOS, null));
|
|
expect(getTitleBottomLeft(), const Offset(390.0, 0.0));
|
|
|
|
await tester.pumpWidget(buildFrame(TargetPlatform.macOS, false));
|
|
expect(getTitleBottomLeft(), Offset.zero);
|
|
|
|
// Clear the widget tree to avoid animating between platforms.
|
|
await tester.pumpWidget(Container(key: UniqueKey()));
|
|
|
|
await tester.pumpWidget(buildFrame(TargetPlatform.windows, null));
|
|
expect(getTitleBottomLeft(), Offset.zero);
|
|
|
|
await tester.pumpWidget(buildFrame(TargetPlatform.windows, true));
|
|
expect(getTitleBottomLeft(), const Offset(390.0, 0.0));
|
|
|
|
// Clear the widget tree to avoid animating between platforms.
|
|
await tester.pumpWidget(Container(key: UniqueKey()));
|
|
|
|
await tester.pumpWidget(buildFrame(TargetPlatform.linux, null));
|
|
expect(getTitleBottomLeft(), Offset.zero);
|
|
|
|
await tester.pumpWidget(buildFrame(TargetPlatform.linux, true));
|
|
expect(getTitleBottomLeft(), const Offset(390.0, 0.0));
|
|
});
|
|
}
|
|
|
|
class TestDelegate extends SliverPersistentHeaderDelegate {
|
|
|
|
const TestDelegate({
|
|
required this.settings,
|
|
});
|
|
|
|
final FlexibleSpaceBarSettings settings;
|
|
|
|
@override
|
|
double get maxExtent => settings.maxExtent;
|
|
|
|
@override
|
|
double get minExtent => settings.minExtent;
|
|
|
|
@override
|
|
Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
|
|
return settings;
|
|
}
|
|
|
|
@override
|
|
bool shouldRebuild(TestDelegate oldDelegate) => false;
|
|
}
|