Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions lib/src/map/widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -141,16 +141,14 @@ class _FlutterMapStateContainer extends State<FlutterMap>
);
final oldCamera = _mapController.camera;
if (_mapController.setNonRotatedSizeWithoutEmittingEvent(nonRotatedSize)) {
final newMapCamera = _mapController.camera;

// Avoid emitting the event during build otherwise if the user calls
// setState in the onMapEvent callback it will throw.
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) {
_mapController.nonRotatedSizeChange(
MapEventSource.nonRotatedSizeChange,
oldCamera,
newMapCamera,
_mapController.camera,
);

_applyInitialCameraFit(constraints);
Expand Down
66 changes: 66 additions & 0 deletions test/layer/tile_layer/tile_update_after_early_fit_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import 'package:flutter/widgets.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:latlong2/latlong.dart';

import '../../test_utils/test_tile_image.dart';

/// Records the zoom of every tile whose image actually starts loading.
class _RecordingTileProvider extends TileProvider {
final loadedZooms = <int>{};

@override
ImageProvider<Object> getImage(
TileCoordinates coordinates, TileLayer options) =>
_RecordingImage(() => loadedZooms.add(coordinates.z));
}

class _RecordingImage extends MemoryImage {
_RecordingImage(this.onResolve) : super(testWhiteTileBytes);

final VoidCallback onResolve;

@override
Future<MemoryImage> obtainKey(ImageConfiguration configuration) {
onResolve();
return super.obtainKey(configuration);
}
}

void main() {
testWidgets(
'camera move scheduled before the first layout loads tiles at the new '
'zoom with a debounced tileUpdateTransformer',
(tester) async {
final controller = MapController();
final provider = _RecordingTileProvider();

// Registered before `FlutterMap`'s own post-frame size change event.
WidgetsBinding.instance.addPostFrameCallback((_) {
controller.move(const LatLng(45, 5), 10);
});

await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: FlutterMap(
mapController: controller,
options: const MapOptions(initialZoom: 3),
children: [
TileLayer(
tileProvider: provider,
tileUpdateTransformer: TileUpdateTransformers.debounce(
const Duration(milliseconds: 50),
),
),
],
),
),
);
await tester.pump(const Duration(milliseconds: 100));

expect(controller.camera.zoom, 10);
expect(provider.loadedZooms, contains(10));
},
);
}