mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Condense nav bar large title in landscape mode (#166956)
## Rotation demo https://github.com/user-attachments/assets/b59d6875-dff7-4b40-9525-565dfd8a2554 ### Portrait mode .automatic https://github.com/user-attachments/assets/88f4f3a2-0f13-4c92-b601-20c20e13f7dc ### Landscape mode .automatic https://github.com/user-attachments/assets/dd5e2373-82e3-41fc-8e83-4002ce5e848e ### Portrait mode .always https://github.com/user-attachments/assets/623d131a-f71b-430d-b84c-0b4519919f56 ### Landscape mode .always https://github.com/user-attachments/assets/5980e8fe-a981-482d-9f77-97f9ab7495c7 Fixes [CupertinoSliverNavigationBar doesn't become compact in landscape mode](https://github.com/flutter/flutter/issues/39254) <details> <summary>Sample code</summary> ```dart import 'package:flutter/cupertino.dart'; void main() => runApp(const NavBarBlueApp()); class NavBarBlueApp extends StatelessWidget { const NavBarBlueApp({super.key}); @override Widget build(BuildContext context) { return CupertinoApp( theme: CupertinoThemeData(), home: MainPage(), ); } } class MainPage extends StatelessWidget { const MainPage({super.key}); @override Widget build(BuildContext context) { return CupertinoPageScaffold( child: SafeArea( child: CustomScrollView( slivers: [ CupertinoSliverNavigationBar.search( stretch: true, searchField: CupertinoSearchTextField( suffixMode: OverlayVisibilityMode.always, suffixIcon: Icon( CupertinoIcons.mic_solid, )), largeTitle: Text('Lists'), bottomMode: NavigationBarBottomMode.always, ), SliverList( delegate: SliverChildBuilderDelegate( (BuildContext context, int index) { return CupertinoListTile( title: Text('Entry $index'), ); }, childCount: 20, ), ), ], ), ), ); } } ``` </details>
This commit is contained in:
parent
651ff0a8f2
commit
96d1b99211
@ -12,6 +12,10 @@ void main() {
|
||||
// The point is to mainly test the cupertino icons that we don't have a
|
||||
// dependency against in the flutter/cupertino package directly.
|
||||
|
||||
// Set window orientation to portrait.
|
||||
tester.view.physicalSize = const Size(2400.0, 3000.0);
|
||||
addTearDown(tester.view.reset);
|
||||
|
||||
final Future<ByteData> font = rootBundle.load(
|
||||
'packages/cupertino_icons/assets/CupertinoIcons.ttf',
|
||||
);
|
||||
|
@ -8,10 +8,16 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
const Offset dragUp = Offset(0.0, -150.0);
|
||||
|
||||
void setWindowToPortrait(WidgetTester tester, {Size size = const Size(2400.0, 3000.0)}) {
|
||||
tester.view.physicalSize = size;
|
||||
addTearDown(tester.view.reset);
|
||||
}
|
||||
|
||||
void main() {
|
||||
testWidgets('Collapse and expand CupertinoSliverNavigationBar changes title position', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
setWindowToPortrait(tester);
|
||||
await tester.pumpWidget(const example.SliverNavBarApp());
|
||||
|
||||
// Large title is visible and at lower position.
|
||||
@ -29,6 +35,7 @@ void main() {
|
||||
testWidgets('Middle widget is visible in both collapsed and expanded states', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
setWindowToPortrait(tester);
|
||||
await tester.pumpWidget(const example.SliverNavBarApp());
|
||||
|
||||
// Navigate to a page that has both middle and large titles.
|
||||
@ -55,6 +62,7 @@ void main() {
|
||||
testWidgets('CupertinoSliverNavigationBar with previous route has back button', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
setWindowToPortrait(tester);
|
||||
await tester.pumpWidget(const example.SliverNavBarApp());
|
||||
|
||||
// Navigate to a page that has back button
|
||||
|
@ -9,10 +9,16 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
const Offset titleDragUp = Offset(0.0, -100.0);
|
||||
const Offset bottomDragUp = Offset(0.0, -50.0);
|
||||
|
||||
void setWindowToPortrait(WidgetTester tester, {Size size = const Size(2400.0, 3000.0)}) {
|
||||
tester.view.physicalSize = size;
|
||||
addTearDown(tester.view.reset);
|
||||
}
|
||||
|
||||
void main() {
|
||||
testWidgets('Collapse and expand CupertinoSliverNavigationBar changes title position', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
setWindowToPortrait(tester);
|
||||
await tester.pumpWidget(const example.SliverNavBarApp());
|
||||
|
||||
// Large title is visible and at lower position.
|
||||
@ -28,6 +34,7 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('Search field is hidden in bottom automatic mode', (WidgetTester tester) async {
|
||||
setWindowToPortrait(tester);
|
||||
await tester.pumpWidget(const example.SliverNavBarApp());
|
||||
|
||||
// Navigate to a page with bottom automatic mode.
|
||||
@ -64,6 +71,7 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('Search field is always shown in bottom always mode', (WidgetTester tester) async {
|
||||
setWindowToPortrait(tester);
|
||||
await tester.pumpWidget(const example.SliverNavBarApp());
|
||||
|
||||
// Navigate to a page with bottom always mode.
|
||||
@ -92,6 +100,7 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('Opens the search view when the search field is tapped', (WidgetTester tester) async {
|
||||
setWindowToPortrait(tester);
|
||||
await tester.pumpWidget(const example.SliverNavBarApp());
|
||||
|
||||
// Navigate to a page with a search field.
|
||||
@ -131,6 +140,7 @@ void main() {
|
||||
testWidgets('CupertinoSliverNavigationBar with previous route has back button', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
setWindowToPortrait(tester);
|
||||
await tester.pumpWidget(const example.SliverNavBarApp());
|
||||
|
||||
// Navigate to the first page.
|
||||
|
@ -8,8 +8,14 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
const Offset dragUp = Offset(0.0, -150.0);
|
||||
|
||||
void setWindowToPortrait(WidgetTester tester, {Size size = const Size(2400.0, 3000.0)}) {
|
||||
tester.view.physicalSize = size;
|
||||
addTearDown(tester.view.reset);
|
||||
}
|
||||
|
||||
void main() {
|
||||
testWidgets('CupertinoSliverNavigationBar bottom widget', (WidgetTester tester) async {
|
||||
setWindowToPortrait(tester);
|
||||
await tester.pumpWidget(const example.SliverNavBarApp());
|
||||
|
||||
final Finder preferredSize = find.byType(PreferredSize);
|
||||
@ -24,6 +30,7 @@ void main() {
|
||||
testWidgets('Collapse and expand CupertinoSliverNavigationBar changes title position', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
setWindowToPortrait(tester);
|
||||
await tester.pumpWidget(const example.SliverNavBarApp());
|
||||
|
||||
// Large title is visible and at lower position.
|
||||
@ -41,6 +48,7 @@ void main() {
|
||||
testWidgets('Middle widget is visible in both collapsed and expanded states', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
setWindowToPortrait(tester);
|
||||
await tester.pumpWidget(const example.SliverNavBarApp());
|
||||
|
||||
// Navigate to a page that has both middle and large titles.
|
||||
@ -67,6 +75,7 @@ void main() {
|
||||
testWidgets('CupertinoSliverNavigationBar with previous route has back button', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
setWindowToPortrait(tester);
|
||||
await tester.pumpWidget(const example.SliverNavBarApp());
|
||||
|
||||
// Navigate to a page that has a back button.
|
||||
|
@ -1149,11 +1149,13 @@ class _CupertinoSliverNavigationBarState extends State<CupertinoSliverNavigation
|
||||
late _NavigationBarStaticComponentsKeys keys;
|
||||
ScrollableState? _scrollableState;
|
||||
_NavigationBarSearchField? preferredSizeSearchField;
|
||||
Widget? effectiveMiddle;
|
||||
late AnimationController _animationController;
|
||||
late CurvedAnimation _searchAnimation;
|
||||
late Animation<double> persistentHeightAnimation;
|
||||
late Animation<double> largeTitleHeightAnimation;
|
||||
bool searchIsActive = false;
|
||||
bool isPortrait = true;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -1169,6 +1171,14 @@ class _CupertinoSliverNavigationBarState extends State<CupertinoSliverNavigation
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
isPortrait = MediaQuery.orientationOf(context) == Orientation.portrait;
|
||||
final Tween<double> largeTitleHeightTween = Tween<double>(
|
||||
begin: isPortrait ? _kNavBarLargeTitleHeightExtension : 0.0,
|
||||
end: 0.0,
|
||||
);
|
||||
largeTitleHeightAnimation = largeTitleHeightTween.animate(_animationController);
|
||||
effectiveMiddle = widget.middle ?? (isPortrait ? null : widget.largeTitle);
|
||||
|
||||
_scrollableState?.position.isScrollingNotifier.removeListener(_handleScrollChange);
|
||||
_scrollableState = Scrollable.maybeOf(context);
|
||||
_scrollableState?.position.isScrollingNotifier.addListener(_handleScrollChange);
|
||||
@ -1203,11 +1213,6 @@ class _CupertinoSliverNavigationBarState extends State<CupertinoSliverNavigation
|
||||
);
|
||||
persistentHeightAnimation = persistentHeightTween.animate(_animationController)
|
||||
..addStatusListener(_handleSearchFieldStatusChanged);
|
||||
final Tween<double> largeTitleHeightTween = Tween<double>(
|
||||
begin: _kNavBarLargeTitleHeightExtension,
|
||||
end: 0.0,
|
||||
);
|
||||
largeTitleHeightAnimation = largeTitleHeightTween.animate(_animationController);
|
||||
}
|
||||
|
||||
void _handleScrollChange() {
|
||||
@ -1221,16 +1226,17 @@ class _CupertinoSliverNavigationBarState extends State<CupertinoSliverNavigation
|
||||
widget.bottomMode == NavigationBarBottomMode.always ? 0.0 : _bottomHeight;
|
||||
final bool canScrollBottom =
|
||||
(widget._searchable || widget.bottom != null) && bottomScrollOffset > 0.0;
|
||||
final double effectiveLargeTitleHeight = isPortrait ? _kNavBarLargeTitleHeightExtension : 0.0;
|
||||
|
||||
// Snap the scroll view to a target determined by the navigation bar's
|
||||
// position.
|
||||
if (canScrollBottom && position.pixels < bottomScrollOffset) {
|
||||
target = position.pixels > bottomScrollOffset / 2 ? bottomScrollOffset : 0.0;
|
||||
} else if (position.pixels > bottomScrollOffset &&
|
||||
position.pixels < bottomScrollOffset + _kNavBarLargeTitleHeightExtension) {
|
||||
position.pixels < bottomScrollOffset + effectiveLargeTitleHeight) {
|
||||
target =
|
||||
position.pixels > bottomScrollOffset + (_kNavBarLargeTitleHeightExtension / 2)
|
||||
? bottomScrollOffset + _kNavBarLargeTitleHeightExtension
|
||||
position.pixels > bottomScrollOffset + (effectiveLargeTitleHeight / 2)
|
||||
? bottomScrollOffset + effectiveLargeTitleHeight
|
||||
: bottomScrollOffset;
|
||||
}
|
||||
|
||||
@ -1280,7 +1286,7 @@ class _CupertinoSliverNavigationBarState extends State<CupertinoSliverNavigation
|
||||
automaticallyImplyLeading: widget.automaticallyImplyLeading,
|
||||
automaticallyImplyTitle: widget.automaticallyImplyTitle,
|
||||
previousPageTitle: widget.previousPageTitle,
|
||||
userMiddle: _animationController.isAnimating ? const Text('') : widget.middle,
|
||||
userMiddle: _animationController.isAnimating ? const Text('') : effectiveMiddle,
|
||||
userTrailing:
|
||||
widget.trailing != null
|
||||
? Visibility(visible: !searchIsActive, child: widget.trailing!)
|
||||
@ -1304,7 +1310,7 @@ class _CupertinoSliverNavigationBarState extends State<CupertinoSliverNavigation
|
||||
: widget.bottom) ??
|
||||
const SizedBox.shrink(),
|
||||
padding: widget.padding,
|
||||
large: true,
|
||||
large: isPortrait,
|
||||
staticBar: false, // This one scrolls.
|
||||
context: context,
|
||||
);
|
||||
@ -1318,7 +1324,7 @@ class _CupertinoSliverNavigationBarState extends State<CupertinoSliverNavigation
|
||||
delegate: _LargeTitleNavigationBarSliverDelegate(
|
||||
keys: keys,
|
||||
components: components,
|
||||
userMiddle: widget.middle,
|
||||
userMiddle: effectiveMiddle,
|
||||
backgroundColor:
|
||||
CupertinoDynamicColor.maybeResolve(widget.backgroundColor, context) ??
|
||||
CupertinoTheme.of(context).barBackgroundColor,
|
||||
@ -1331,7 +1337,7 @@ class _CupertinoSliverNavigationBarState extends State<CupertinoSliverNavigation
|
||||
heroTag: widget.heroTag,
|
||||
persistentHeight: persistentHeightAnimation.value + MediaQuery.paddingOf(context).top,
|
||||
largeTitleHeight: largeTitleHeightAnimation.value,
|
||||
alwaysShowMiddle: widget.alwaysShowMiddle && widget.middle != null,
|
||||
alwaysShowMiddle: widget.alwaysShowMiddle && effectiveMiddle != null,
|
||||
stretchConfiguration:
|
||||
widget.stretch && !searchIsActive ? OverScrollHeaderStretchConfiguration() : null,
|
||||
enableBackgroundFilterBlur: widget.enableBackgroundFilterBlur,
|
||||
|
@ -16,6 +16,11 @@ import '../widgets/semantics_tester.dart';
|
||||
|
||||
int count = 0;
|
||||
|
||||
void setWindowToPortrait(WidgetTester tester, {Size size = const Size(2400.0, 3000.0)}) {
|
||||
tester.view.physicalSize = size;
|
||||
addTearDown(tester.view.reset);
|
||||
}
|
||||
|
||||
void main() {
|
||||
testWidgets('Middle still in center with asymmetrical actions', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
@ -305,6 +310,7 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('Can specify custom brightness', (WidgetTester tester) async {
|
||||
setWindowToPortrait(tester);
|
||||
await tester.pumpWidget(
|
||||
const CupertinoApp(
|
||||
home: CupertinoNavigationBar(
|
||||
@ -498,6 +504,7 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('Large title nav bar scrolls', (WidgetTester tester) async {
|
||||
setWindowToPortrait(tester);
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
@ -573,6 +580,7 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('User specified middle is always visible in sliver', (WidgetTester tester) async {
|
||||
setWindowToPortrait(tester);
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
final Key segmentedControlsKey = UniqueKey();
|
||||
@ -629,6 +637,7 @@ void main() {
|
||||
testWidgets(
|
||||
'User specified middle is only visible when sliver is collapsed if alwaysShowMiddle is false',
|
||||
(WidgetTester tester) async {
|
||||
setWindowToPortrait(tester);
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
@ -682,6 +691,7 @@ void main() {
|
||||
);
|
||||
|
||||
testWidgets('Small title can be overridden', (WidgetTester tester) async {
|
||||
setWindowToPortrait(tester);
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
@ -1171,6 +1181,7 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('Sliver large title golden', (WidgetTester tester) async {
|
||||
setWindowToPortrait(tester);
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
home: RepaintBoundary(
|
||||
@ -1736,6 +1747,7 @@ void main() {
|
||||
(WidgetTester tester) async {
|
||||
const Text trailingText = Text('Bar Button');
|
||||
const Text titleText = Text('Large Title');
|
||||
setWindowToPortrait(tester);
|
||||
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
@ -1874,6 +1886,7 @@ void main() {
|
||||
testWidgets(
|
||||
'CupertinoSliverNavigationBar magnifies upon over-scroll and shrinks back once over-scroll ends',
|
||||
(WidgetTester tester) async {
|
||||
setWindowToPortrait(tester);
|
||||
const Text titleText = Text('Large Title');
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -1985,6 +1998,7 @@ void main() {
|
||||
const double largeTitleHeight = 44.0;
|
||||
const double bottomHeight = 10.0;
|
||||
final ScrollController controller = ScrollController();
|
||||
setWindowToPortrait(tester);
|
||||
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
@ -2042,6 +2056,7 @@ void main() {
|
||||
const double persistentHeight = 44.0;
|
||||
const double largeTitleHeight = 44.0;
|
||||
const double bottomHeight = 10.0;
|
||||
setWindowToPortrait(tester);
|
||||
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
@ -2119,6 +2134,7 @@ void main() {
|
||||
) async {
|
||||
const double bottomHeight = 10.0;
|
||||
const double bottomDisplacement = 96.0;
|
||||
setWindowToPortrait(tester);
|
||||
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
@ -2166,6 +2182,7 @@ void main() {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
const double largeTitleHeight = 52.0;
|
||||
setWindowToPortrait(tester);
|
||||
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
@ -2212,6 +2229,7 @@ void main() {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
const double largeTitleHeight = 52.0;
|
||||
setWindowToPortrait(tester);
|
||||
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
@ -2258,6 +2276,7 @@ void main() {
|
||||
addTearDown(scrollController.dispose);
|
||||
const double largeTitleHeight = 52.0;
|
||||
const double bottomHeight = 100.0;
|
||||
setWindowToPortrait(tester);
|
||||
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
@ -2323,6 +2342,7 @@ void main() {
|
||||
addTearDown(scrollController.dispose);
|
||||
const double largeTitleHeight = 52.0;
|
||||
const double bottomHeight = 100.0;
|
||||
setWindowToPortrait(tester);
|
||||
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
@ -2392,6 +2412,7 @@ void main() {
|
||||
addTearDown(scrollController.dispose);
|
||||
const double largeTitleHeight = 52.0;
|
||||
const double bottomHeight = 100.0;
|
||||
setWindowToPortrait(tester);
|
||||
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
@ -2459,6 +2480,7 @@ void main() {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
const double largeTitleHeight = 52.0;
|
||||
setWindowToPortrait(tester);
|
||||
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
@ -2542,6 +2564,7 @@ void main() {
|
||||
testWidgets('CupertinoSliverNavigationBar.search field collapses nav bar on tap', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
setWindowToPortrait(tester);
|
||||
await tester.pumpWidget(
|
||||
const CupertinoApp(
|
||||
home: CustomScrollView(
|
||||
@ -2609,8 +2632,7 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('CupertinoSliverNavigationBar.search golden tests', (WidgetTester tester) async {
|
||||
await tester.binding.setSurfaceSize(const Size(390, 850));
|
||||
addTearDown(() => tester.binding.setSurfaceSize(null));
|
||||
setWindowToPortrait(tester);
|
||||
await tester.pumpWidget(
|
||||
const CupertinoApp(
|
||||
home: RepaintBoundary(
|
||||
@ -2672,6 +2694,7 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('onSearchableBottomTap callback', (WidgetTester tester) async {
|
||||
setWindowToPortrait(tester);
|
||||
const Color activeSearchColor = Color(0x0000000A);
|
||||
const Color inactiveSearchColor = Color(0x0000000B);
|
||||
bool isSearchActive = false;
|
||||
@ -2750,6 +2773,7 @@ void main() {
|
||||
testWidgets(
|
||||
'CupertinoSliverNavigationBar.search large title and cancel buttons fade during search animation',
|
||||
(WidgetTester tester) async {
|
||||
setWindowToPortrait(tester);
|
||||
await tester.pumpWidget(
|
||||
const CupertinoApp(
|
||||
home: CustomScrollView(
|
||||
@ -2826,6 +2850,52 @@ void main() {
|
||||
expect(cancelOpacity.opacity.value, 0.0);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets('Large title is hidden if middle is provided in landscape mode', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
const String largeTitle = 'Large title';
|
||||
const String middle = 'Middle';
|
||||
await tester.pumpWidget(
|
||||
const CupertinoApp(
|
||||
home: CustomScrollView(
|
||||
slivers: <Widget>[
|
||||
CupertinoSliverNavigationBar.search(
|
||||
largeTitle: Text(largeTitle),
|
||||
middle: Text(middle),
|
||||
searchField: CupertinoSearchTextField(),
|
||||
),
|
||||
SliverFillRemaining(child: SizedBox(height: 1000.0)),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(find.text(largeTitle), findsNothing);
|
||||
expect(find.text(middle), findsOneWidget);
|
||||
expect(find.byType(CupertinoSearchTextField), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Large title is shown in middle position in landscape mode', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
const String largeTitle = 'Large title';
|
||||
await tester.pumpWidget(
|
||||
const CupertinoApp(
|
||||
home: CustomScrollView(
|
||||
slivers: <Widget>[
|
||||
CupertinoSliverNavigationBar.search(
|
||||
largeTitle: Text(largeTitle),
|
||||
searchField: CupertinoSearchTextField(),
|
||||
),
|
||||
SliverFillRemaining(child: SizedBox(height: 1000.0)),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
expect(find.text(largeTitle), findsOneWidget);
|
||||
expect(find.byType(CupertinoSearchTextField), findsOneWidget);
|
||||
});
|
||||
}
|
||||
|
||||
class _ExpectStyles extends StatelessWidget {
|
||||
|
@ -132,6 +132,11 @@ void checkOpacity(WidgetTester tester, Finder finder, double opacity) {
|
||||
);
|
||||
}
|
||||
|
||||
void setWindowToPortrait(WidgetTester tester, {Size size = const Size(2400.0, 3000.0)}) {
|
||||
tester.view.physicalSize = size;
|
||||
addTearDown(tester.view.reset);
|
||||
}
|
||||
|
||||
void main() {
|
||||
testWidgets('Bottom middle moves between middle and back label', (WidgetTester tester) async {
|
||||
await startTransitionBetween(tester, fromTitle: 'Page 1');
|
||||
@ -666,6 +671,7 @@ void main() {
|
||||
testWidgets('Middle is not shown if alwaysShowMiddle is false and the nav bar is expanded', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
setWindowToPortrait(tester);
|
||||
const Widget userMiddle = Placeholder();
|
||||
await startTransitionBetween(
|
||||
tester,
|
||||
@ -987,6 +993,7 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('Bottom large title moves to top back label', (WidgetTester tester) async {
|
||||
setWindowToPortrait(tester);
|
||||
await startTransitionBetween(
|
||||
tester,
|
||||
from: const CupertinoSliverNavigationBar(),
|
||||
@ -1045,6 +1052,7 @@ void main() {
|
||||
testWidgets('Bottom CupertinoSliverNavigationBar.bottom fades and slides out from the left', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
setWindowToPortrait(tester);
|
||||
await startTransitionBetween(
|
||||
tester,
|
||||
from: const CupertinoSliverNavigationBar(
|
||||
@ -1081,6 +1089,7 @@ void main() {
|
||||
testWidgets('Bottom CupertinoNavigationBar.bottom fades and slides out from the left', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
setWindowToPortrait(tester);
|
||||
await startTransitionBetween(
|
||||
tester,
|
||||
from: const CupertinoNavigationBar(
|
||||
@ -1117,6 +1126,7 @@ void main() {
|
||||
testWidgets(
|
||||
'CupertinoSliverNavigationBar.bottom clips its contents mid-transition when scrolled',
|
||||
(WidgetTester tester) async {
|
||||
setWindowToPortrait(tester);
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
builder: (BuildContext context, Widget? navigator) {
|
||||
@ -1233,6 +1243,7 @@ void main() {
|
||||
);
|
||||
|
||||
testWidgets('Long title turns into the word back mid transition', (WidgetTester tester) async {
|
||||
setWindowToPortrait(tester);
|
||||
await startTransitionBetween(
|
||||
tester,
|
||||
from: const CupertinoSliverNavigationBar(),
|
||||
@ -1289,6 +1300,7 @@ void main() {
|
||||
testWidgets('Bottom large title and top back label transitions their font', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
setWindowToPortrait(tester);
|
||||
await startTransitionBetween(
|
||||
tester,
|
||||
from: const CupertinoSliverNavigationBar(),
|
||||
@ -1397,6 +1409,7 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('Top large title fades in and slides in from the right', (WidgetTester tester) async {
|
||||
setWindowToPortrait(tester);
|
||||
await startTransitionBetween(
|
||||
tester,
|
||||
to: const CupertinoSliverNavigationBar(),
|
||||
@ -1427,6 +1440,7 @@ void main() {
|
||||
testWidgets('Top large title fades in and slides in from the left in RTL', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
setWindowToPortrait(tester);
|
||||
await startTransitionBetween(
|
||||
tester,
|
||||
to: const CupertinoSliverNavigationBar(),
|
||||
@ -1460,6 +1474,7 @@ void main() {
|
||||
) async {
|
||||
const double horizontalPadding = 16.0; // _kNavBarEdgePadding
|
||||
const double height = 30.0;
|
||||
setWindowToPortrait(tester);
|
||||
await startTransitionBetween(
|
||||
tester,
|
||||
toTitle: 'Page 2',
|
||||
@ -1503,7 +1518,7 @@ void main() {
|
||||
// The nav bar bottom is horizontally aligned to the large title.
|
||||
expect(
|
||||
tester.getTopLeft(flying(tester, find.byType(Placeholder))).dx,
|
||||
largeTitleOffset.dx - horizontalPadding,
|
||||
moreOrLessEquals(largeTitleOffset.dx - horizontalPadding, epsilon: 0.01),
|
||||
);
|
||||
});
|
||||
|
||||
@ -1581,6 +1596,7 @@ void main() {
|
||||
) async {
|
||||
int bottomBuildTimes = 0;
|
||||
int topBuildTimes = 0;
|
||||
setWindowToPortrait(tester);
|
||||
await startTransitionBetween(
|
||||
tester,
|
||||
from: CupertinoNavigationBar(
|
||||
|
@ -51,6 +51,9 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('Large title auto-populates with title', (WidgetTester tester) async {
|
||||
// Set window orientation to portrait.
|
||||
tester.view.physicalSize = const Size(2400.0, 3000.0);
|
||||
addTearDown(tester.view.reset);
|
||||
await tester.pumpWidget(const CupertinoApp(home: Placeholder()));
|
||||
|
||||
tester
|
||||
|
Loading…
Reference in New Issue
Block a user