Skip to content

Commit

Permalink
Fine-grained MediaQuery dependencies to rebuild only when needed (#…
Browse files Browse the repository at this point in the history
…1523)

Previously, the broad dependency triggered rebuilds when the keyboard came up even when rendered in a Scaffold() with resizeToAvoidBottomInset set to false. This caused a lot of jank for me, i.e. triggering full-map-rebuilds at animation pace.
  • Loading branch information
ignatz authored May 14, 2023
1 parent 00285e3 commit 7538c66
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 4 deletions.
6 changes: 3 additions & 3 deletions lib/src/map/flutter_map_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ class FlutterMapState extends MapGestureMixin
Widget build(BuildContext context) {
super.build(context);

final DeviceGestureSettings? gestureSettings =
MediaQuery.maybeOf(context)?.gestureSettings;
final DeviceGestureSettings gestureSettings =
MediaQuery.gestureSettingsOf(context);
final Map<Type, GestureRecognizerFactory> gestures =
<Type, GestureRecognizerFactory>{};

Expand Down Expand Up @@ -178,7 +178,7 @@ class FlutterMapState extends MapGestureMixin
// zero constraints which were actually provided by the parent widget.
bool _parentConstraintsAreSet(
BuildContext context, BoxConstraints constraints) =>
constraints.maxWidth != 0 || MediaQuery.of(context).size != Size.zero;
constraints.maxWidth != 0 || MediaQuery.sizeOf(context) != Size.zero;

Widget _buildMap() {
return ClipRect(
Expand Down
48 changes: 47 additions & 1 deletion test/flutter_map_test.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_map/plugin_api.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:latlong2/latlong.dart';

Expand Down Expand Up @@ -32,4 +32,50 @@ void main() {
expect(find.byType(MarkerLayer), findsWidgets);
expect(find.byType(FlutterLogo), findsOneWidget);
});

testWidgets(
'FlutterMap - Bottom ViewInsets (e.g. keyboard) do not trigger rebuilds.',
(tester) async {
int builds = 0;

final map = FlutterMap(
options: MapOptions(
center: LatLng(45.5231, -122.6765),
zoom: 13,
),
children: [
Builder(
builder: (BuildContext context) {
final _ = FlutterMapState.of(context);
builds++;
return Container();
},
),
],
);

Widget wrapMapInApp({required double bottomInset}) {
return Directionality(
textDirection: TextDirection.ltr,
child: MediaQuery(
data: MediaQueryData(
viewInsets: EdgeInsets.only(bottom: bottomInset),
),
child: Scaffold(
resizeToAvoidBottomInset: false,
body: map,
),
),
);
}

await tester.pumpWidget(wrapMapInApp(bottomInset: 0));
expect(find.byType(FlutterMap), findsOneWidget);

// Emulate a keyboard popping up by putting a non-zero bottom ViewInset.
await tester.pumpWidget(wrapMapInApp(bottomInset: 100));

// The map should not have rebuild after the first build.
expect(builds, equals(1));
});
}

0 comments on commit 7538c66

Please sign in to comment.