Skip to content
Open
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
8 changes: 7 additions & 1 deletion lib/src/layer/marker_layer/marker_layer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,13 @@ class _MarkerLayerState extends State<MarkerLayer> {
Offset(shiftedX, pxPoint.dy) - pixelOrigin;

return Positioned(
key: m.key,
// Keep the caller's key on the main world so find.byKey and
// per-marker identity are unchanged; derive a distinct key for
// each repeated world so a keyed marker does not produce
// duplicate sibling keys in the Stack (#2229).
key: m.key == null || worldShift == 0
? m.key
: ValueKey((m.key, worldShift)),
width: m.width,
height: m.height,
left: shiftedLocalPoint.dx - right,
Expand Down
63 changes: 63 additions & 0 deletions test/layer/marker_key_worlds_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import 'package:flutter/material.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_provider.dart';

void main() {
testWidgets(
'a keyed marker repeated across worlds does not produce duplicate keys (#2229)',
(tester) async {
const key = Key('m-1');
final markers = <Marker>[
const Marker(
key: key,
width: 20,
height: 20,
point: LatLng(0, 0),
child: FlutterLogo(),
),
];

// A wide viewport at low zoom shows the world several times, so a keyed
// marker is drawn once per visible world. Before the fix, those copies
// shared m.key and the layer's Stack threw "Duplicate keys".
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: Center(
child: SizedBox(
width: 900,
height: 200,
child: FlutterMap(
options: const MapOptions(
initialCenter: LatLng(0, 0),
initialZoom: 0,
),
children: [
TileLayer(
urlTemplate:
'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
tileProvider: TestTileProvider(),
),
MarkerLayer(markers: markers),
],
),
),
),
),
),
);

expect(tester.takeException(), isNull);
// The marker really is drawn more than once (worlds repeated).
expect(
tester.widgetList(find.byType(FlutterLogo)).length,
greaterThan(1),
);
// The main world keeps the caller's key, so find.byKey resolves to one.
expect(find.byKey(key), findsOneWidget);
},
);
}