Skip to content

Commit ebd138d

Browse files
authored
[flutter_adaptive_scaffold] use MediaQuery.sizeOf instead of MediaQuery.of to prevent unnecessary rebuilds (#6544)
the `isActive` method uses `MediaQuery.of(context).size.width`, which triggers widget rebuilds whenever a property of `MediaQuery` changes, even when the size.width doesn't change. instead, we should be using `MediaQuery.sizeOf(context).width`. fixes: flutter/flutter#146801
1 parent af6fae4 commit ebd138d

File tree

4 files changed

+47
-5
lines changed

4 files changed

+47
-5
lines changed

packages/flutter_adaptive_scaffold/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.1.10+2
2+
3+
* Reduce rebuilds when invoking `isActive` method.
4+
15
## 0.1.10+1
26

37
* Removes a broken design document link from the README.

packages/flutter_adaptive_scaffold/lib/src/breakpoints.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ class WidthPlatformBreakpoint extends Breakpoint {
9595

9696
// Null boundaries are unbounded, assign the max/min of their associated
9797
// direction on a number line.
98-
final double width = MediaQuery.of(context).size.width;
98+
final double width = MediaQuery.sizeOf(context).width;
9999
final double lowerBound = begin ?? double.negativeInfinity;
100100
final double upperBound = end ?? double.infinity;
101101

@@ -126,6 +126,6 @@ abstract class Breakpoint {
126126
const Breakpoint();
127127

128128
/// A method that returns true based on conditions related to the context of
129-
/// the screen such as MediaQuery.of(context).size.width.
129+
/// the screen such as MediaQuery.sizeOf(context).width.
130130
bool isActive(BuildContext context);
131131
}

packages/flutter_adaptive_scaffold/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: flutter_adaptive_scaffold
22
description: Widgets to easily build adaptive layouts, including navigation elements.
3-
version: 0.1.10+1
3+
version: 0.1.10+2
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_adaptive_scaffold%22
55
repository: https://github.com/flutter/packages/tree/main/packages/flutter_adaptive_scaffold
66

packages/flutter_adaptive_scaffold/test/breakpoint_test.dart

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
import 'package:flutter/foundation.dart';
6-
import 'package:flutter/widgets.dart';
5+
import 'package:flutter/material.dart';
6+
import 'package:flutter_adaptive_scaffold/src/breakpoints.dart';
77
import 'package:flutter_test/flutter_test.dart';
88
import 'simulated_layout.dart';
99

@@ -51,4 +51,42 @@ void main() {
5151
expect(find.byKey(const Key('Breakpoints.largeDesktop')), findsOneWidget);
5252
expect(find.byKey(const Key('Breakpoints.largeMobile')), findsNothing);
5353
}, variant: TargetPlatformVariant.desktop());
54+
55+
testWidgets('Breakpoint.isActive should not trigger unnecessary rebuilds',
56+
(WidgetTester tester) async {
57+
await tester.pumpWidget(const DymmyWidget());
58+
expect(find.byKey(const Key('button')), findsOneWidget);
59+
60+
// First build.
61+
expect(DymmyWidget.built, isTrue);
62+
63+
// Invoke `isActive` method.
64+
await tester.tap(find.byKey(const Key('button')));
65+
DymmyWidget.built = false;
66+
67+
// Should not rebuild after modifying any property in `MediaQuery`.
68+
tester.platformDispatcher.textScaleFactorTestValue = 2;
69+
await tester.pumpAndSettle();
70+
expect(DymmyWidget.built, isFalse);
71+
});
72+
}
73+
74+
class DymmyWidget extends StatelessWidget {
75+
const DymmyWidget({super.key});
76+
77+
static bool built = false;
78+
@override
79+
Widget build(BuildContext context) {
80+
built = true;
81+
return Directionality(
82+
textDirection: TextDirection.ltr,
83+
child: ElevatedButton(
84+
key: const Key('button'),
85+
onPressed: () {
86+
Breakpoints.small.isActive(context);
87+
},
88+
child: const SizedBox(),
89+
),
90+
);
91+
}
5492
}

0 commit comments

Comments
 (0)