@@ -11,74 +11,72 @@ import 'package:flutter/rendering.dart';
11
11
import 'package:flutter/services.dart' ;
12
12
import 'package:flutter_test/flutter_test.dart' ;
13
13
14
- void main () {
15
- testWidgets ('RenderParagraph relayout upon system fonts changes' , (WidgetTester tester) async {
16
- await tester.pumpWidget (
17
- const MaterialApp (
18
- home: Text ('text widget' ),
19
- ),
20
- );
21
- final RenderObject renderObject = tester.renderObject (find.text ('text widget' ));
14
+ Future <void > verifyMarkedNeedsLayoutDuringTransientCallbacksPhase (WidgetTester tester, RenderObject renderObject) async {
15
+ assert (! renderObject.debugNeedsLayout);
22
16
23
- const Map <String , dynamic > data = < String , dynamic > {
24
- 'type' : 'fontsChange' ,
25
- };
26
- await ServicesBinding .instance.defaultBinaryMessenger.handlePlatformMessage (
27
- 'flutter/system' ,
28
- SystemChannels .system.codec.encodeMessage (data),
29
- (ByteData ? data) { },
30
- );
17
+ const Map <String , dynamic > data = < String , dynamic > {
18
+ 'type' : 'fontsChange' ,
19
+ };
20
+ await ServicesBinding .instance.defaultBinaryMessenger.handlePlatformMessage (
21
+ 'flutter/system' ,
22
+ SystemChannels .system.codec.encodeMessage (data),
23
+ (ByteData ? data) { },
24
+ );
31
25
32
- final Completer <bool > animation = Completer <bool >();
33
- tester.binding.scheduleFrameCallback ((Duration timeStamp) {
34
- animation.complete (renderObject.debugNeedsLayout);
35
- });
36
- expect (renderObject.debugNeedsLayout, isFalse);
37
- await tester.pump ();
38
- expect (await animation.future, isTrue);
26
+ final Completer <bool > animation = Completer <bool >();
27
+ tester.binding.scheduleFrameCallback ((Duration timeStamp) {
28
+ animation.complete (renderObject.debugNeedsLayout);
39
29
});
40
30
41
- testWidgets ('Safe to query RenderParagraph for text layout after system fonts changes' , (WidgetTester tester) async {
31
+ // The fonts change does not mark the render object as needing layout
32
+ // immediately.
33
+ expect (renderObject.debugNeedsLayout, isFalse);
34
+ await tester.pump ();
35
+ expect (await animation.future, isTrue);
36
+ }
37
+
38
+ void main () {
39
+ testWidgets ('RenderParagraph relayout upon system fonts changes' , (WidgetTester tester) async {
42
40
await tester.pumpWidget (
43
41
const MaterialApp (
44
42
home: Text ('text widget' ),
45
43
),
46
44
);
47
- const Map <String , dynamic > data = < String , dynamic > {
48
- 'type' : 'fontsChange' ,
49
- };
50
- await ServicesBinding .instance.defaultBinaryMessenger.handlePlatformMessage (
51
- 'flutter/system' ,
52
- SystemChannels .system.codec.encodeMessage (data),
53
- (ByteData ? data) { },
54
- );
55
- final RenderParagraph paragraph = tester.renderObject <RenderParagraph >(find.text ('text widget' ));
56
- Object ? exception;
57
- try {
58
- paragraph.getPositionForOffset (Offset .zero);
59
- paragraph.hitTest (BoxHitTestResult (), position: Offset .zero);
60
- } catch (e) {
61
- exception = e;
62
- }
63
- expect (exception, isNull);
45
+ final RenderObject renderObject = tester.renderObject (find.text ('text widget' ));
46
+ await verifyMarkedNeedsLayoutDuringTransientCallbacksPhase (tester, renderObject);
64
47
});
65
48
49
+ testWidgets (
50
+ 'Safe to query a RelayoutWhenSystemFontsChangeMixin for text layout after system fonts changes' ,
51
+ (WidgetTester tester) async {
52
+ final _RenderCustomRelayoutWhenSystemFontsChange child = _RenderCustomRelayoutWhenSystemFontsChange ();
53
+ await tester.pumpWidget (
54
+ Directionality (
55
+ textDirection: TextDirection .ltr,
56
+ child: WidgetToRenderBoxAdapter (renderBox: child),
57
+ ),
58
+ );
59
+ const Map <String , dynamic > data = < String , dynamic > {
60
+ 'type' : 'fontsChange' ,
61
+ };
62
+ await ServicesBinding .instance.defaultBinaryMessenger.handlePlatformMessage (
63
+ 'flutter/system' ,
64
+ SystemChannels .system.codec.encodeMessage (data),
65
+ (ByteData ? data) { },
66
+ );
67
+ expect (child.hasValidTextLayout, isTrue);
68
+ },
69
+ );
70
+
66
71
testWidgets ('RenderEditable relayout upon system fonts changes' , (WidgetTester tester) async {
67
72
await tester.pumpWidget (
68
73
const MaterialApp (
69
74
home: SelectableText ('text widget' ),
70
75
),
71
76
);
72
- const Map <String , dynamic > data = < String , dynamic > {
73
- 'type' : 'fontsChange' ,
74
- };
75
- await ServicesBinding .instance.defaultBinaryMessenger.handlePlatformMessage (
76
- 'flutter/system' ,
77
- SystemChannels .system.codec.encodeMessage (data),
78
- (ByteData ? data) { },
79
- );
77
+
80
78
final EditableTextState state = tester.state (find.byType (EditableText ));
81
- expect ( state.renderEditable.debugNeedsLayout, isTrue );
79
+ await verifyMarkedNeedsLayoutDuringTransientCallbacksPhase (tester, state.renderEditable);
82
80
});
83
81
84
82
testWidgets ('Banner repaint upon system fonts changes' , (WidgetTester tester) async {
@@ -210,11 +208,8 @@ void main() {
210
208
SystemChannels .system.codec.encodeMessage (data),
211
209
(ByteData ? data) { },
212
210
);
213
- final RenderObject renderObject = tester.renderObject (find.byType (RangeSlider ));
214
-
215
- late bool sliderBoxNeedsLayout;
216
- renderObject.visitChildren ((RenderObject child) {sliderBoxNeedsLayout = child.debugNeedsLayout;});
217
- expect (sliderBoxNeedsLayout, isTrue);
211
+ final RenderObject renderObject = tester.renderObject (find.byWidgetPredicate ((Widget widget) => widget.runtimeType.toString () == '_RangeSliderRenderObjectWidget' ));
212
+ await verifyMarkedNeedsLayoutDuringTransientCallbacksPhase (tester, renderObject);
218
213
});
219
214
220
215
testWidgets ('Slider relayout upon system fonts changes' , (WidgetTester tester) async {
@@ -228,17 +223,9 @@ void main() {
228
223
),
229
224
),
230
225
);
231
- const Map <String , dynamic > data = < String , dynamic > {
232
- 'type' : 'fontsChange' ,
233
- };
234
- await ServicesBinding .instance.defaultBinaryMessenger.handlePlatformMessage (
235
- 'flutter/system' ,
236
- SystemChannels .system.codec.encodeMessage (data),
237
- (ByteData ? data) { },
238
- );
239
226
// _RenderSlider is the last render object in the tree.
240
227
final RenderObject renderObject = tester.allRenderObjects.last;
241
- expect (renderObject.debugNeedsLayout, isTrue );
228
+ await verifyMarkedNeedsLayoutDuringTransientCallbacksPhase (tester, renderObject );
242
229
});
243
230
244
231
testWidgets ('TimePicker relayout upon system fonts changes' , (WidgetTester tester) async {
@@ -289,3 +276,19 @@ void main() {
289
276
expect (renderObject.debugNeedsPaint, isTrue);
290
277
});
291
278
}
279
+
280
+ class _RenderCustomRelayoutWhenSystemFontsChange extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
281
+ bool hasValidTextLayout = false ;
282
+
283
+ @override
284
+ void systemFontsDidChange () {
285
+ super .systemFontsDidChange ();
286
+ hasValidTextLayout = false ;
287
+ }
288
+
289
+ @override
290
+ void performLayout () {
291
+ size = constraints.biggest;
292
+ hasValidTextLayout = true ;
293
+ }
294
+ }
0 commit comments