ItemizedOverlay Rotate marker and crash

不打扰是莪最后的温柔 提交于 2019-12-03 21:52:58

It seems the natural API choice, RotateDrawable, is braindead in that you can only use it from inflated layout. I have adapted Mark Murphy's code referenced in the question into the below activity which shows the New York markers spinning, using an alternative RotateDrawable which wraps a contained drawable in a more flexible way:

import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.OverlayItem;
import java.util.ArrayList;
import java.util.List;

public class NooYawk extends MapActivity {
    private MapView map=null;
    private MyLocationOverlay me=null;
    private SitesOverlay sites=null;
    Handler handler = new Handler();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        map=(MapView)findViewById(R.id.map);

        map.getController().setCenter(getPoint(40.76793169992044, -73.98180484771729));
        map.getController().setZoom(17);
        map.setBuiltInZoomControls(true);

        me=new MyLocationOverlay(this, map);
        map.getOverlays().add(me);

        sites=new SitesOverlay();
        map.getOverlays().add(sites);
        map.invalidate();           
    }

    @Override
    public void onResume() {
        super.onResume();

        me.enableCompass();
    }       

    @Override
    public void onPause() {
        super.onPause();

        me.disableCompass();
    }       

    @Override
    protected boolean isRouteDisplayed() {
        return(false);
    }

    private GeoPoint getPoint(double lat, double lon) {
        return(new GeoPoint((int)(lat*1000000.0), (int)(lon*1000000.0)));
    }

    private class SitesOverlay extends ItemizedOverlay<CustomItem> {
        private List<CustomItem> items=new ArrayList<CustomItem>();

        public SitesOverlay() {
            super(null);
            items.add(new CustomItem(getPoint(40.748963847316034, -73.96807193756104),
                    "UN", "United Nations",getMarker(R.drawable.blue_full_marker)));
            items.add(new CustomItem(getPoint(40.76866299974387, -73.98268461227417),
                    "Lincoln Center", "Home of Jazz at Lincoln Center", getMarker(R.drawable.orange_full_marker)));
            items.add(new CustomItem(getPoint(40.765136435316755, -73.97989511489868), 
                    "Carnegie Hall", "Where you go with practice, practice, practice", getMarker(R.drawable.green_full_marker)));
            items.add(new CustomItem(getPoint(40.70686417491799,-74.01572942733765), "The Downtown Club",
                    "Original home of the Heisman Trophy", getMarker(R.drawable.purple_full_marker)));
            populate();
        }

        @Override
        protected CustomItem createItem(int i) {
            return(items.get(i));
        }

        @Override
        public void draw(Canvas canvas, MapView mapView, boolean shadow) {
            super.draw(canvas, mapView, shadow);
            handler.post(new Runnable() {
                @Override 
                public void run() {
                    for (CustomItem item : items) {
                        item.marker.rotate();
                    }
                    map.invalidate();
                }               
            });
        }

        @Override
        public int size() {
            return(items.size());
        }


        private Drawable getMarker(int resource) {
            Drawable marker=getResources().getDrawable(resource);

            marker.setBounds(0, 0, marker.getIntrinsicWidth(),
                                                marker.getIntrinsicHeight());
            boundCenter(marker);

            return(marker);
        }
    }

    //
    // A RotateDrawable that isn't braindead.
    //
    private class RotateDrawable extends Drawable {
        private Drawable mDrawable;
        private float mPivotX = 0.5f;
        private float mPivotY = 0.5f;
        private float mCurrentDegrees = 0f;
        public RotateDrawable(Drawable drawable) {
            this.mDrawable = drawable;
        }
        public void rotate() {
            mCurrentDegrees+=5;
            if (mCurrentDegrees>=360) {
                mCurrentDegrees-=360;
            }
        }
        public void draw(Canvas canvas) {
            int saveCount = canvas.save();
            Rect bounds = mDrawable.getBounds();
            int w = bounds.right - bounds.left;
            int h = bounds.bottom - bounds.top;
            float px = w * mPivotX;
            float py = h * mPivotY;
            canvas.rotate(mCurrentDegrees, 0, 0);
            mDrawable.draw(canvas);
            canvas.restoreToCount(saveCount);
        }

        @Override public int getOpacity() {
            return mDrawable.getOpacity();
        }

        @Override
        public void setAlpha(int arg0) {
            mDrawable.setAlpha(arg0);
        }

        @Override
        public void setColorFilter(ColorFilter arg0) {
            mDrawable.setColorFilter(arg0);
        }
    }

    class CustomItem extends OverlayItem {
        public RotateDrawable marker=null;
        CustomItem(GeoPoint pt, String name, String snippet, Drawable marker) {
            super(pt, name, snippet);
            this.marker=new RotateDrawable(marker);
        }


        @Override
        public Drawable getMarker(int stateBitset) {
            Drawable result=(marker);

            setState(result, stateBitset);

            return(result);
        }
    }

}

Any questions, feel free to ask. :-)

100rabh

In that case Lee I suggest you give a try to AnimationDrawable

    AnimationDrawable frameAnimation = 
(AnimationDrawable) getResources().getDrawable(R.drawable.spin_animationm);

EDIT: In the meantime came over another useful post ' moving-icons-on-a-android-mapview' which suggests using a timer thread in the onDraw().

Hope that helps.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!