Skip to content

Commit cf5a50c

Browse files
Merge pull request #12 from valentingrigorean/bug-map-update-flutter-3.0.0
Bug map update flutter 3.0.0
2 parents bc0d0e1 + 6f4ebe2 commit cf5a50c

File tree

2 files changed

+49
-2
lines changed

2 files changed

+49
-2
lines changed

android/src/main/java/com/valentingrigorean/arcgis_maps_flutter/map/ArcgisMapController.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import android.content.Context;
44
import android.util.Log;
5+
import android.view.Choreographer;
56
import android.view.View;
67
import android.view.ViewGroup;
78
import android.widget.FrameLayout;
@@ -19,6 +20,8 @@
1920
import com.esri.arcgisruntime.geometry.GeometryEngine;
2021
import com.esri.arcgisruntime.geometry.Point;
2122
import com.esri.arcgisruntime.layers.Layer;
23+
import com.esri.arcgisruntime.loadable.LoadStatusChangedEvent;
24+
import com.esri.arcgisruntime.loadable.LoadStatusChangedListener;
2225
import com.esri.arcgisruntime.location.LocationDataSource;
2326
import com.esri.arcgisruntime.mapping.ArcGISMap;
2427
import com.esri.arcgisruntime.mapping.LayerList;
@@ -93,6 +96,8 @@ final class ArcgisMapController implements DefaultLifecycleObserver, PlatformVie
9396

9497
private boolean disposed = false;
9598

99+
private boolean loadedCallbackPending = false;
100+
96101
ArcgisMapController(
97102
int id,
98103
Context context,
@@ -258,6 +263,7 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result
258263
}
259264
break;
260265
case "map#setMap": {
266+
invalidateMapIfNeeded();
261267
final Viewpoint viewpoint = mapView.getCurrentViewpoint(Viewpoint.Type.CENTER_AND_SCALE);
262268
changeMapType(call.arguments);
263269
if (viewpoint != null) {
@@ -395,11 +401,13 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result
395401
}
396402
break;
397403
case "layers#update": {
404+
invalidateMapIfNeeded();
398405
layersController.updateFromArgs(call.arguments);
399406
result.success(null);
400407
}
401408
break;
402409
case "markers#update": {
410+
invalidateMapIfNeeded();
403411
List<Object> markersToAdd = call.argument("markersToAdd");
404412
markersController.addMarkers(markersToAdd);
405413
List<Object> markersToChange = call.argument("markersToChange");
@@ -410,12 +418,14 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result
410418
}
411419
break;
412420
case "map#clearMarkerSelection": {
421+
invalidateMapIfNeeded();
413422
selectionPropertiesHandler.reset();
414423
markersController.clearSelectedMarker();
415424
result.success(null);
416425
}
417426
break;
418427
case "polygons#update": {
428+
invalidateMapIfNeeded();
419429
List<Object> polygonsToAdd = call.argument("polygonsToAdd");
420430
polygonsController.addPolygons(polygonsToAdd);
421431
List<Object> polygonsToChange = call.argument("polygonsToChange");
@@ -426,6 +436,7 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result
426436
}
427437
break;
428438
case "polylines#update": {
439+
invalidateMapIfNeeded();
429440
List<Object> polylinesToAdd = call.argument("polylinesToAdd");
430441
polylinesController.addPolylines(polylinesToAdd);
431442
List<Object> polylinesToChange = call.argument("polylinesToChange");
@@ -522,6 +533,42 @@ private void destroyMapViewIfNecessary() {
522533
}
523534
}
524535

536+
/**
537+
* Invalidates the map view after the map has finished rendering.
538+
*
539+
* <p>gmscore GL renderer uses a {@link android.view.TextureView}. Android platform views that are
540+
* displayed as a texture after Flutter v3.0.0. require that the view hierarchy is notified after
541+
* all drawing operations have been flushed.
542+
*
543+
* <p>Since the GL renderer doesn't use standard Android views, and instead uses GL directly, we
544+
* notify the view hierarchy by invalidating the view.
545+
*
546+
* <p>To workaround this limitation, wait two frames. This ensures that at least the frame budget
547+
* (16.66ms at 60hz) have passed since the drawing operation was issued.
548+
*/
549+
private void invalidateMapIfNeeded() {
550+
if (mapView == null || mapView.getMap() == null || loadedCallbackPending) {
551+
return;
552+
}
553+
554+
loadedCallbackPending = true;
555+
mapView.getMap().addDoneLoadingListener(() -> {
556+
loadedCallbackPending = false;
557+
postFrameCallback(() -> postFrameCallback(
558+
() -> {
559+
if (mapView != null) {
560+
mapView.invalidate();
561+
}
562+
}));
563+
});
564+
}
565+
566+
private static void postFrameCallback(Runnable f) {
567+
Choreographer.getInstance()
568+
.postFrameCallback(frameTimeNanos -> f.run());
569+
}
570+
571+
525572
private void handleTimeAwareLayerInfos(MethodChannel.Result result) {
526573
final ArcGISMap map = mapView.getMap();
527574
if (map == null || map.getOperationalLayers().size() == 0) {

pubspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: arcgis_maps_flutter
22
description: A new flutter plugin project.
3-
version: 0.0.4+2
3+
version: 0.0.4+3
44
homepage:
55

66
environment:
@@ -24,7 +24,7 @@ dev_dependencies:
2424
sdk: flutter
2525
flutter_lints: ^2.0.1
2626
mockito: ^5.2.0
27-
build_runner: ^2.1.11
27+
build_runner: ^2.2.0
2828

2929
# For information on the generic Dart part of this file, see the
3030
# following page: https://dart.dev/tools/pub/pubspec

0 commit comments

Comments
 (0)