问题
I wonder if it is be possible to animate Google Maps markers rotations along x- and y-axis like how we'd rotate an ImageView using ObjectAnimator around x-axis and/or y-axis. Apparently, one can rotate (change) the orientation of a marker clockwise, which is along z-axis (in X-Y plane), but I seem to be unable to find something similar for even rotating a marker (bitmap) around x- or y-axis. I have found few discussions like this which might be somehow related to what I'm looking for but I am rather confused on how to go about this. Any help is greatly appreciated!
UPDATE I I did further research and came up with a proposal on how to tackle this problem:
Google Map
Markerhas a setter method for setting its icon, referred to assetIcon. Not only through theMarkerOptionbut also as an standalone method to reset theMarkericon. This method expects aBitmapDescriptorto be passed in in order to update the icon. UsingBitmapDescriptorFactoryone can easily get aBitmapDescriptorfrom a givenBitmapobject.Since Google Maps
Markerdoesn't support 3D rotations, we need to somehow rotate theBitmapwhich goes in place of theMarkericon outside of theMarkeritself. One way to do this, as far as my findings go, to create aCanvasand aCameraobjects, while former is linked to theDrawableto be 3D rotated, the latter is used to actually perform the 3D rotations.Using
Camerahelper methods likerotateX,rotateY, androtateZ, in addition to any necessary translations, one can obtain a customizedMatrixinstance. By applying thisMatrixtoCanvasusing, for example,concatorsetMatrixmethod, we enforce the the rotations.The drawable can be linked to
Canvas, that is, we may useDrawable.draw(Canvas canvas)method to actually draw into theBitmapwhile 3D transformations are applied. Assuming that theCanvasobject is linked to theBitmap. This way the transformed version of the drawable should now be held by theBitmapinstance.Using
Markersetter methodsetIcon, we first recycle the olderBitmapDescriptorand then create a new one, and pass that object tosetIcon.
Questions: I wonder if this is the best way to accomplish what I'm looking for. Moreover, how to actually accomplish an animation. I am certain an approach like the one using Animation and overriding it applyTransformation(float interpolatedTime, Transformation t) won't work as it is only applicable to View objects. I further believe I'm better off using ValueAnimator which provides the necessary timing engine for running animations, that is calculating the animated values and set them on target object, in this case the rotation value.
UPDATE II
I have come up with the following snippet which is pretty much self-explanatory. Unfortunately, once the animation starts, the icon is removed and nothing else. I captured the logs to make sure the ValueAnimator actually works and it turns out that it does indeed. I also removed all transformations and made sure the Matrix is identity but that didn't help. Getting the Drawable and attempting to draw that into Bitmap instance via Canvas still doesn't work. In fact, when the animation begins, the icon is simply removed. To verify if bitmap file is really created to be replaced, I tried to sample and save the bitmap into SDCARD as PNG format. It's confirmed that the saved PNGs are all blank and that's why the icon is seen to be removed. Any thought?
private void animateMarker() {
if (mCamera == null) {
mCamera = new Camera();
}
ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
animator.setDuration(300);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// float interpolatedTime = ((Float) (animation.getAnimatedValue())).floatValue();
// final double radians = Math.PI * interpolatedTime;
// float degrees = (float) (180.0 * radians / Math.PI);
final Matrix matrix = new Matrix();
// mCamera.translate(0.0f, 0.0f, (float) (150.0 * Math.sin(radians)));
// mCamera.rotateX(degrees);
// mCamera.rotateY(degrees);
// mCamera.rotateZ(degrees);
// mCamera.getMatrix(matrix);
Resources resources = mContext.getResources();
Drawable drawable = resources.getDrawable(R.drawable.custom_pin);
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
// mCamera.applyToCanvas(canvas);
// canvas.setMatrix(matrix);
// drawable.draw(canvas);
canvas.drawBitmap(bitmap, matrix, null);
mMarkerSetLocation.setIcon(mBitmapDescriptorFactory.fromBitmap(bitmap));
}
});
animator.start();
}
来源:https://stackoverflow.com/questions/32554925/android-animate-rotation-of-map-marker-around-x-and-y-axis