4
4
import android .graphics .Bitmap ;
5
5
import android .graphics .BitmapFactory ;
6
6
import android .graphics .Canvas ;
7
+ import android .graphics .Color ;
7
8
import android .graphics .drawable .Animatable ;
8
9
import android .graphics .drawable .Drawable ;
9
10
import android .net .Uri ;
@@ -75,6 +76,7 @@ public class AirMapMarker extends AirMapFeature {
75
76
76
77
private boolean tracksViewChanges = true ;
77
78
private boolean tracksViewChangesActive = false ;
79
+ private boolean hasViewChanges = true ;
78
80
79
81
private boolean hasCustomMarkerView = false ;
80
82
@@ -108,7 +110,7 @@ public void onFinalImageSet(
108
110
CloseableReference .closeSafely (imageReference );
109
111
}
110
112
}
111
- update ();
113
+ update (true );
112
114
}
113
115
};
114
116
@@ -150,12 +152,12 @@ public void setCoordinate(ReadableMap coordinate) {
150
152
if (marker != null ) {
151
153
marker .setPosition (position );
152
154
}
153
- update ();
155
+ update (false );
154
156
}
155
157
156
158
public void setIdentifier (String identifier ) {
157
159
this .identifier = identifier ;
158
- update ();
160
+ update (false );
159
161
}
160
162
161
163
public String getIdentifier () {
@@ -167,60 +169,60 @@ public void setTitle(String title) {
167
169
if (marker != null ) {
168
170
marker .setTitle (title );
169
171
}
170
- update ();
172
+ update (false );
171
173
}
172
174
173
175
public void setSnippet (String snippet ) {
174
176
this .snippet = snippet ;
175
177
if (marker != null ) {
176
178
marker .setSnippet (snippet );
177
179
}
178
- update ();
180
+ update (false );
179
181
}
180
182
181
183
public void setRotation (float rotation ) {
182
184
this .rotation = rotation ;
183
185
if (marker != null ) {
184
186
marker .setRotation (rotation );
185
187
}
186
- update ();
188
+ update (false );
187
189
}
188
190
189
191
public void setFlat (boolean flat ) {
190
192
this .flat = flat ;
191
193
if (marker != null ) {
192
194
marker .setFlat (flat );
193
195
}
194
- update ();
196
+ update (false );
195
197
}
196
198
197
199
public void setDraggable (boolean draggable ) {
198
200
this .draggable = draggable ;
199
201
if (marker != null ) {
200
202
marker .setDraggable (draggable );
201
203
}
202
- update ();
204
+ update (false );
203
205
}
204
206
205
207
public void setZIndex (int zIndex ) {
206
208
this .zIndex = zIndex ;
207
209
if (marker != null ) {
208
210
marker .setZIndex (zIndex );
209
211
}
210
- update ();
212
+ update (false );
211
213
}
212
214
213
215
public void setOpacity (float opacity ) {
214
216
this .opacity = opacity ;
215
217
if (marker != null ) {
216
218
marker .setAlpha (opacity );
217
219
}
218
- update ();
220
+ update (false );
219
221
}
220
222
221
223
public void setMarkerHue (float markerHue ) {
222
224
this .markerHue = markerHue ;
223
- update ();
225
+ update (false );
224
226
}
225
227
226
228
public void setAnchor (double x , double y ) {
@@ -230,7 +232,7 @@ public void setAnchor(double x, double y) {
230
232
if (marker != null ) {
231
233
marker .setAnchor (anchorX , anchorY );
232
234
}
233
- update ();
235
+ update (false );
234
236
}
235
237
236
238
public void setCalloutAnchor (double x , double y ) {
@@ -240,7 +242,7 @@ public void setCalloutAnchor(double x, double y) {
240
242
if (marker != null ) {
241
243
marker .setInfoWindowAnchor (calloutAnchorX , calloutAnchorY );
242
244
}
243
- update ();
245
+ update (false );
244
246
}
245
247
246
248
public void setTracksViewChanges (boolean tracksViewChanges ) {
@@ -257,18 +259,36 @@ private void updateTracksViewChanges() {
257
259
ViewChangesTracker .getInstance ().addMarker (this );
258
260
} else {
259
261
ViewChangesTracker .getInstance ().removeMarker (this );
262
+
263
+ // Let it render one more time to avoid race conditions.
264
+ // i.e. Image onLoad ->
265
+ // ViewChangesTracker may not get a chance to render ->
266
+ // setState({ tracksViewChanges: false }) ->
267
+ // image loaded but not rendered.
268
+ updateMarkerIcon ();
260
269
}
261
270
}
262
271
263
- public boolean updateCustomMarkerIcon () {
272
+ public boolean updateCustomForTracking () {
264
273
if (!tracksViewChangesActive )
265
274
return false ;
266
275
267
- marker . setIcon ( getIcon () );
276
+ updateMarkerIcon ( );
268
277
269
278
return true ;
270
279
}
271
280
281
+ public void updateMarkerIcon () {
282
+ if (!hasViewChanges ) return ;
283
+
284
+ if (!hasCustomMarkerView ) {
285
+ // No more updates for this, as it's a simple icon
286
+ hasViewChanges = false ;
287
+ }
288
+
289
+ marker .setIcon (getIcon ());
290
+ }
291
+
272
292
public LatLng interpolate (float fraction , LatLng a , LatLng b ) {
273
293
double lat = (b .latitude - a .latitude ) * fraction + a .latitude ;
274
294
double lng = (b .longitude - a .longitude ) * fraction + a .longitude ;
@@ -293,9 +313,11 @@ public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) {
293
313
}
294
314
295
315
public void setImage (String uri ) {
316
+ hasViewChanges = true ;
317
+
296
318
if (uri == null ) {
297
319
iconBitmapDescriptor = null ;
298
- update ();
320
+ update (true );
299
321
} else if (uri .startsWith ("http://" ) || uri .startsWith ("https://" ) ||
300
322
uri .startsWith ("file://" ) || uri .startsWith ("asset://" )) {
301
323
ImageRequest imageRequest = ImageRequestBuilder
@@ -323,7 +345,7 @@ public void setImage(String uri) {
323
345
drawable .draw (canvas );
324
346
}
325
347
}
326
- update ();
348
+ update (true );
327
349
}
328
350
}
329
351
@@ -344,7 +366,21 @@ public void addView(View child, int index) {
344
366
hasCustomMarkerView = true ;
345
367
updateTracksViewChanges ();
346
368
}
347
- update ();
369
+ update (true );
370
+ }
371
+
372
+ @ Override
373
+ public void requestLayout () {
374
+ super .requestLayout ();
375
+
376
+ if (getChildCount () == 0 ) {
377
+ if (hasCustomMarkerView ) {
378
+ hasCustomMarkerView = false ;
379
+ clearDrawableCache ();
380
+ updateTracksViewChanges ();
381
+ update (true );
382
+ }
383
+ }
348
384
}
349
385
350
386
@ Override
@@ -404,12 +440,13 @@ private MarkerOptions fillMarkerOptions(MarkerOptions options) {
404
440
return options ;
405
441
}
406
442
407
- public void update () {
443
+ public void update (boolean updateIcon ) {
408
444
if (marker == null ) {
409
445
return ;
410
446
}
411
447
412
- marker .setIcon (getIcon ());
448
+ if (updateIcon )
449
+ updateMarkerIcon ();
413
450
414
451
if (anchorIsSet ) {
415
452
marker .setAnchor (anchorX , anchorY );
@@ -427,14 +464,33 @@ public void update() {
427
464
public void update (int width , int height ) {
428
465
this .width = width ;
429
466
this .height = height ;
430
- update ();
467
+
468
+ update (true );
469
+ }
470
+
471
+ private Bitmap mLastBitmapCreated = null ;
472
+
473
+ private void clearDrawableCache () {
474
+ mLastBitmapCreated = null ;
431
475
}
432
476
433
477
private Bitmap createDrawable () {
434
478
int width = this .width <= 0 ? 100 : this .width ;
435
479
int height = this .height <= 0 ? 100 : this .height ;
436
480
this .buildDrawingCache ();
437
- Bitmap bitmap = Bitmap .createBitmap (width , height , Bitmap .Config .ARGB_8888 );
481
+
482
+ // Do not create the doublebuffer-bitmap each time. reuse it to save memory.
483
+ Bitmap bitmap = mLastBitmapCreated ;
484
+
485
+ if (bitmap == null ||
486
+ bitmap .isRecycled () ||
487
+ bitmap .getWidth () != width ||
488
+ bitmap .getHeight () != height ) {
489
+ bitmap = Bitmap .createBitmap (width , height , Bitmap .Config .ARGB_8888 );
490
+ mLastBitmapCreated = bitmap ;
491
+ } else {
492
+ bitmap .eraseColor (Color .TRANSPARENT );
493
+ }
438
494
439
495
Canvas canvas = new Canvas (bitmap );
440
496
this .draw (canvas );
0 commit comments