我正在使用 android maps v2works 很好,我可以在位置上添加和删除标记 onLong Touch。
问题: 我想将标记慢慢放到触摸位置,即我希望用户看到标记从屏幕顶部浮动到它被放置的位置(触摸位置)。
目前; 标记仅出现在触摸的位置,因此您必须抬起手指才能看到它已被放下。很高兴看到它来自屏幕顶部。
谢谢。
我正在使用 android maps v2works 很好,我可以在位置上添加和删除标记 onLong Touch。
问题: 我想将标记慢慢放到触摸位置,即我希望用户看到标记从屏幕顶部浮动到它被放置的位置(触摸位置)。
目前; 标记仅出现在触摸的位置,因此您必须抬起手指才能看到它已被放下。很高兴看到它来自屏幕顶部。
谢谢。
您可以使用与此类似的代码(未经测试)来实现此目的:
final LatLng target = ...;
final long duration = 400;
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
Projection proj = map.getProjection();
Point startPoint = proj.toScreenLocation(target);
startPoint.y = 0;
final LatLng startLatLng = proj.fromScreenLocation(startPoint);
final Interpolator interpolator = new LinearInterpolator();
handler.post(new Runnable() {
@Override
public void run() {
long elapsed = SystemClock.uptimeMillis() - start;
float t = interpolator.getInterpolation((float) elapsed / duration);
double lng = t * target.longitude + (1 - t) * startLatLng.longitude;
double lat = t * target.latitude + (1 - t) * startLatLng.latitude;
marker.setPosition(new LatLng(lat, lng));
if (t < 1.0) {
// Post again 10ms later.
handler.postDelayed(this, 10);
} else {
// animation ended
}
}
});
我将 MaciejGórski 的方法与此 gist中的代码相结合。此外,还添加了反弹效果。
public class MyBounceInterpolator implements android.view.animation.Interpolator {
double mAmplitude = 1;
double mFrequency = 10;
public MyBounceInterpolator(double amplitude, double frequency) {
mAmplitude = amplitude;
mFrequency = frequency;
}
public float getInterpolation(float time) {
double amplitude = mAmplitude;
if (amplitude == 0) { amplitude = 0.05; }
// The interpolation curve equation:
// -e^(-time / amplitude) * cos(frequency * time) + 1
//
// View the graph live: https://www.desmos.com/calculator/6gbvrm5i0s
return (float) (-1 * Math.pow(Math.E, -time/ mAmplitude) * Math.cos(mFrequency * time) + 1);
}
}
void dropMarker(final Marker marker, GoogleMap map) {
final LatLng finalPosition = new LatLng(marker.getPosition().latitude, marker.getPosition().longitude);
Projection projection = map.getProjection();
Point startPoint = projection.toScreenLocation(finalPosition);
startPoint.y = 0;
final LatLng startLatLng = projection.fromScreenLocation(startPoint);
final Interpolator interpolator = new MyBounceInterpolator(0.11, 4.6);
TypeEvaluator<LatLng> typeEvaluator = new TypeEvaluator<LatLng>() {
@Override
public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) {
float t = interpolator.getInterpolation(fraction);
double lng = t * finalPosition.longitude + (1 - t) * startLatLng.longitude;
double lat = t * finalPosition.latitude + (1 - t) * startLatLng.latitude;
return new LatLng(lat, lng);
}
};
Property<Marker, LatLng> property = Property.of(Marker.class, LatLng.class, "position");
ObjectAnimator animator = ObjectAnimator.ofObject(marker, property, typeEvaluator, finalPosition);
animator.setDuration(400);
animator.start();
}
效果很好,但在我看来,有时标记距离目标还有一步之遥,所以我只添加了一行:
if (t < 1.0) {
// Post again 10ms later.
handler.postDelayed(this, 50);
} else {
// animation ended
marker.setPosition(target);
}
希望能帮助到你。
我已经采用了您的方式,但有一个问题是地图上的标记位置不正确。我认为计算下面的命令不正确。因此动画完成后,最终结果与原始 Lat,Lng 不同。
双 lng = t * target.longitude + (1 - t) * startLatLng.longitude; 双纬度 = t * target.latitude + (1 - t) * startLatLng.latitude;