我遇到了一些关于在我的应用程序的地图视图上绘制标记的问题,并决定创建一个测试
package com.mapbox.mapboxsdk.testapp.activity.annotation;
import android.animation.ObjectAnimator;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.PointF;
import android.graphics.RectF;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import com.mapbox.mapboxsdk.MapboxAccountManager;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.annotations.MarkerView;
import com.mapbox.mapboxsdk.annotations.MarkerViewOptions;
import com.mapbox.mapboxsdk.geometry.ILatLng;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.maps.Projection;
import com.mapbox.mapboxsdk.testapp.R;
import java.util.ArrayList;
import java.util.Collection;
public class AnimatedMarkerActivity2 extends AppCompatActivity {
private MapView mapView;
private MarkerView dMarker;
private MarkerView[] dMarkers;
private boolean mIsDragged = false;
private float mDx;
private float mDy;
private ArrayList draggableMarkerList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Mapbox access token is configured here. This needs to be called either in your application
// object or in the same activity which contains the mapview.
// This contains the MapView in XML and needs to be called after the account manager
setContentView(R.layout.activity_annotation_animated_marker);
mapView = (MapView) findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(final MapboxMap mapboxMap)
{
dMarkers = new MarkerView[10];
draggableMarkerList = new ArrayList();
for(int i=0; i<10; i++)
{
dMarkers[i] = mapboxMap.addMarker(new MarkerViewOptions()
.position(new LatLng(51.502615, 4.972326+(i*0.01))));
draggableMarkerList.add(dMarkers[i]);
}
mapView.setOnTouchListener(new View.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
boolean dragged = false;
for(int i=0; i<draggableMarkerList.size(); i++)
{
dragged = drag(mapboxMap, i, v, event);
}
return dragged;
}
});
// mapboxMap.setOnMapClickListener(new MapboxMap.OnMapClickListener() {
// @Override
// public void onMapClick(@NonNull LatLng point) {
//
// // When the user clicks on the map, we want to animate the marker to that
// // location.
// ValueAnimator markerAnimator = ObjectAnimator.ofObject(dMarker, "position",
// new LatLngEvaluator(), dMarker.getPosition(), point);
// markerAnimator.setDuration(2000);
// markerAnimator.start();
// }
// });
}
});
}
private boolean drag(MapboxMap mapviewMap, int i, View v, MotionEvent event)
{
final int action = event.getActionMasked();
dMarker = (MarkerView) draggableMarkerList.get(i);
if(action == MotionEvent.ACTION_DOWN)
{
Projection projection = mapviewMap.getProjection();
// TODO: 08/04/2016 extend the area of movement in the getdrawingbounds()
Bitmap drawable = dMarker.getIcon().getBitmap();
float halfWidth = drawable.getWidth()/2;
PointF markerPosPx = projection.toScreenLocation(dMarker.getPosition());
RectF boundRect = new RectF(markerPosPx.x-halfWidth,
markerPosPx.y-halfWidth,
markerPosPx.x+halfWidth,
markerPosPx.y+halfWidth);
float dp = 25;
Resources resources = Resources.getSystem();
DisplayMetrics metrics = resources.getDisplayMetrics();
float px = dp * (metrics.densityDpi / 160f);
boundRect.left = boundRect.left - px;
boundRect.right = boundRect.right + px;
boundRect.top = boundRect.top - px;
boundRect.bottom = boundRect.bottom + px;
if(boundRect.contains(event.getX(), event.getY()))
{
mIsDragged = true;
//markerPosPx is current position of marker in pixels
mDx = markerPosPx.x - event.getX();
mDy = markerPosPx.y - event.getY();
}
}
if(mIsDragged)
{
if((action == MotionEvent.ACTION_CANCEL) || (action == MotionEvent.ACTION_UP))
{
mIsDragged = false;
}
else if(action == MotionEvent.ACTION_MOVE)
{
Projection pj = mapviewMap.getProjection();
ILatLng pos;
pos = pj.fromScreenLocation(new PointF(event.getX() + mDx, event.getY() + mDy));
LatLng position = new LatLng(pos.getLatitude(), pos.getLongitude());
dMarker.setPosition(position);
for(int j=0; j<10; j++)
{
dMarkers[j].setPosition(new LatLng(pos.getLatitude(), pos.getLongitude()+(j*0.01)));
}
Log.d("", Double.valueOf(pos.getLatitude()).toString());
}
}
return mIsDragged;
}
@Override
protected void onStart()
{
super.onStart();
mapView.onStart();
}
@Override
public void onResume() {
super.onResume();
mapView.onResume();
}
@Override
public void onPause() {
super.onPause();
mapView.onPause();
}
@Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
@Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
@Override
protected void onStop() {
super.onStop();
mapView.onStop();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
private static class LatLngEvaluator implements TypeEvaluator<LatLng> {
// Method is used to interpolate the marker animation.
private LatLng latLng = new LatLng();
@Override
public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) {
latLng.setLatitude(startValue.getLatitude()
+ ((endValue.getLatitude() - startValue.getLatitude()) * fraction));
latLng.setLongitude(startValue.getLongitude()
+ ((endValue.getLongitude() - startValue.getLongitude()) * fraction));
return latLng;
}
}
}
}
您可以在以下链接中找到此代码演示的 gif
我已经绘制了 10 个标记,它们都在 0.01 的经度距离处,每当拖动一个标记时,所有标记的位置都会改变,如果我们移动相机,我们可以观察到当它们返回地图视图时,它们不是立即绘制的,而是需要一点时间,有时它们会消失一会儿,在测试过程中我还发现如果某些标记超出地图视图然后更改它们的位置,那么它们不会'即使他们的新位置在显示的屏幕范围内,也不会出现在地图视图中。
我打开了一张票,解释了我的问题,但我还没有弄清楚,但我强烈怀疑这次测试中发现的问题与我的问题有关(在标记上设置新位置时闪烁)