From 6e26197ef1993f333305438a8686622378fcff9d Mon Sep 17 00:00:00 2001 From: Martijn van Dijk Date: Wed, 4 Sep 2024 02:16:07 +0200 Subject: [PATCH] [flutter_adaptive_scaffold] Fix breakpoint not being active in certain cases like foldables (#7549) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit *Replace this paragraph with a description of what this PR is changing or adding, and why. Consider including before/after screenshots.* As pointed out by the docs on this: > Available width and height are classified separately, so at any point in time, your app has two window size classes—one for width, one for height. Available width is usually more important than available height due to the ubiquity of vertical scrolling, so the width window size class is likely more relevant to your app's UI. *List which issues are fixed by this PR. You must list at least one issue.* --- .../flutter_adaptive_scaffold/CHANGELOG.md | 4 + .../lib/src/breakpoints.dart | 9 +- .../flutter_adaptive_scaffold/pubspec.yaml | 2 +- .../test/breakpoint_test.dart | 105 +++++++++++++++++- .../test/simulated_layout.dart | 4 +- 5 files changed, 116 insertions(+), 8 deletions(-) diff --git a/packages/flutter_adaptive_scaffold/CHANGELOG.md b/packages/flutter_adaptive_scaffold/CHANGELOG.md index b716f19066ee..83d3716b01ec 100644 --- a/packages/flutter_adaptive_scaffold/CHANGELOG.md +++ b/packages/flutter_adaptive_scaffold/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.5 + +* Fix breakpoint not being active in certain cases like foldables. + ## 0.2.4 * Compare breakpoints to each other using operators. diff --git a/packages/flutter_adaptive_scaffold/lib/src/breakpoints.dart b/packages/flutter_adaptive_scaffold/lib/src/breakpoints.dart index a8493f7901c9..91568cedeac8 100644 --- a/packages/flutter_adaptive_scaffold/lib/src/breakpoints.dart +++ b/packages/flutter_adaptive_scaffold/lib/src/breakpoints.dart @@ -284,6 +284,7 @@ class Breakpoint { final double width = MediaQuery.sizeOf(context).width; final double height = MediaQuery.sizeOf(context).height; final Orientation orientation = MediaQuery.orientationOf(context); + final bool isPortrait = orientation == Orientation.portrait; final double lowerBoundWidth = beginWidth ?? double.negativeInfinity; final double upperBoundWidth = endWidth ?? double.infinity; @@ -295,11 +296,9 @@ class Breakpoint { ? width >= lowerBoundWidth : width >= lowerBoundWidth && width < upperBoundWidth; - final bool isHeightActive = isDesktop(context) || - orientation == Orientation.portrait || - (orientation == Orientation.landscape && andUp - ? isWidthActive || height >= lowerBoundHeight - : height >= lowerBoundHeight && height < upperBoundHeight); + final bool isHeightActive = isPortrait || isWidthActive || andUp + ? isWidthActive || height >= lowerBoundHeight + : height >= lowerBoundHeight && height < upperBoundHeight; return isWidthActive && isHeightActive && isRightPlatform; } diff --git a/packages/flutter_adaptive_scaffold/pubspec.yaml b/packages/flutter_adaptive_scaffold/pubspec.yaml index e811357628c1..64979c63aa50 100644 --- a/packages/flutter_adaptive_scaffold/pubspec.yaml +++ b/packages/flutter_adaptive_scaffold/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_adaptive_scaffold description: Widgets to easily build adaptive layouts, including navigation elements. -version: 0.2.4 +version: 0.2.5 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_adaptive_scaffold%22 repository: https://github.com/flutter/packages/tree/main/packages/flutter_adaptive_scaffold diff --git a/packages/flutter_adaptive_scaffold/test/breakpoint_test.dart b/packages/flutter_adaptive_scaffold/test/breakpoint_test.dart index d3ab31fbdb7e..978582a32075 100644 --- a/packages/flutter_adaptive_scaffold/test/breakpoint_test.dart +++ b/packages/flutter_adaptive_scaffold/test/breakpoint_test.dart @@ -517,6 +517,23 @@ void main() { await tester.pumpAndSettle(); expect(find.byKey(const Key('Breakpoints.smallMobile')), findsOneWidget); expect(find.byKey(const Key('Breakpoints.mediumMobile')), findsNothing); + expect(find.byKey(const Key('Breakpoints.small')), findsNothing); + expect(find.byKey(const Key('Breakpoints.smallDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.medium')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumLarge')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.mediumLargeMobile')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumLargeDesktop')), + findsNothing); + expect(find.byKey(const Key('Breakpoints.large')), findsNothing); + expect(find.byKey(const Key('Breakpoints.largeMobile')), findsNothing); + expect(find.byKey(const Key('Breakpoints.largeDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.extraLarge')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.extraLargeMobile')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.extraLargeDesktop')), findsNothing); }); testWidgets( @@ -526,7 +543,24 @@ void main() { SimulatedLayout.smallLandscapeMediumPortrait.slot(tester)); await tester.pumpAndSettle(); expect(find.byKey(const Key('Breakpoints.smallMobile')), findsNothing); - expect(find.byKey(const Key('Breakpoints.mediumMobile')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumMobile')), findsOneWidget); + expect(find.byKey(const Key('Breakpoints.small')), findsNothing); + expect(find.byKey(const Key('Breakpoints.smallDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.medium')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumLarge')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.mediumLargeMobile')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumLargeDesktop')), + findsNothing); + expect(find.byKey(const Key('Breakpoints.large')), findsNothing); + expect(find.byKey(const Key('Breakpoints.largeMobile')), findsNothing); + expect(find.byKey(const Key('Breakpoints.largeDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.extraLarge')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.extraLargeMobile')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.extraLargeDesktop')), findsNothing); }); testWidgets( @@ -537,6 +571,22 @@ void main() { await tester.pumpAndSettle(); expect(find.byKey(const Key('Breakpoints.smallMobile')), findsOneWidget); expect(find.byKey(const Key('Breakpoints.largeMobile')), findsNothing); + expect(find.byKey(const Key('Breakpoints.small')), findsNothing); + expect(find.byKey(const Key('Breakpoints.smallDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.medium')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumLarge')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.mediumLargeMobile')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumLargeDesktop')), + findsNothing); + expect(find.byKey(const Key('Breakpoints.large')), findsNothing); + expect(find.byKey(const Key('Breakpoints.largeDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.extraLarge')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.extraLargeMobile')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.extraLargeDesktop')), findsNothing); }); testWidgets( @@ -547,6 +597,48 @@ void main() { await tester.pumpAndSettle(); expect(find.byKey(const Key('Breakpoints.smallMobile')), findsNothing); expect(find.byKey(const Key('Breakpoints.largeMobile')), findsNothing); + expect(find.byKey(const Key('Breakpoints.small')), findsNothing); + expect(find.byKey(const Key('Breakpoints.smallDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.medium')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumLarge')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumLargeMobile')), + findsOneWidget); + expect(find.byKey(const Key('Breakpoints.mediumLargeDesktop')), + findsNothing); + expect(find.byKey(const Key('Breakpoints.large')), findsNothing); + expect(find.byKey(const Key('Breakpoints.largeDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.extraLarge')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.extraLargeMobile')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.extraLargeDesktop')), findsNothing); + }); + + testWidgets( + 'Layout for mediumLargeLandscapeMediumPortrait shows correct slot configuration', + (WidgetTester tester) async { + await tester.pumpWidget( + SimulatedLayout.mediumLargeLandscapeMediumPortrait.slot(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.smallMobile')), findsNothing); + expect(find.byKey(const Key('Breakpoints.largeMobile')), findsNothing); + expect(find.byKey(const Key('Breakpoints.small')), findsNothing); + expect(find.byKey(const Key('Breakpoints.smallDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.medium')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumLarge')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumLargeMobile')), + findsOneWidget); + expect(find.byKey(const Key('Breakpoints.mediumLargeDesktop')), + findsNothing); + expect(find.byKey(const Key('Breakpoints.large')), findsNothing); + expect(find.byKey(const Key('Breakpoints.largeDesktop')), findsNothing); + expect(find.byKey(const Key('Breakpoints.extraLarge')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.extraLargeMobile')), findsNothing); + expect( + find.byKey(const Key('Breakpoints.extraLargeDesktop')), findsNothing); }); }); @@ -673,6 +765,17 @@ void main() { expect(find.byKey(const Key('Breakpoints.small')), findsNothing); expect(find.byKey(const Key('Breakpoints.mediumAndUp')), findsOneWidget); }); + + testWidgets( + 'slotAndUp shows correct slot for mediumLargeLandscapeMediumPortrait layout', + (WidgetTester tester) async { + // mediumLargeLandscapeMediumPortrait layout should show the mediumAndUp slot. + await tester.pumpWidget( + SimulatedLayout.mediumLargeLandscapeMediumPortrait.slotAndUp(tester)); + await tester.pumpAndSettle(); + expect(find.byKey(const Key('Breakpoints.small')), findsNothing); + expect(find.byKey(const Key('Breakpoints.mediumAndUp')), findsOneWidget); + }); }); // Test for `spacing`. diff --git a/packages/flutter_adaptive_scaffold/test/simulated_layout.dart b/packages/flutter_adaptive_scaffold/test/simulated_layout.dart index afa5e1a311c1..01fba796b6c5 100644 --- a/packages/flutter_adaptive_scaffold/test/simulated_layout.dart +++ b/packages/flutter_adaptive_scaffold/test/simulated_layout.dart @@ -123,7 +123,9 @@ enum SimulatedLayout { smallPortraitMediumLargeLandscape( width: 360, height: 900, navSlotKey: 'bottomNavigation'), smallLandscapeMediumLargePortrait( - width: 900, height: 360, navSlotKey: 'primaryNavigation'); + width: 900, height: 360, navSlotKey: 'primaryNavigation'), + mediumLargeLandscapeMediumPortrait( + width: 841, height: 668, navSlotKey: 'primaryNavigation'); const SimulatedLayout({ required double width,