有点奇怪的帖子,因为这是我之前发布的,认为它已经解决但没有!
我有一种情况需要为每个标记使用自定义Drawable,我需要的效果是将标记旋转一定数量的度数,并且我可能完全错误地对待它。
首先,我使用优秀的知识共享,因为这确实有效,只有在我添加后才会中断!
https://github.com/commonsguy/cw-advandroid/tree/master/Maps/NooYawkAsync
上一篇文章和代码在这里
Android Maps NullPointerException ItemizedOverlay
如果有人能够推荐一种更好,更稳定的方式来获得旋转的Drawable并让我走上正确的道路,那将会非常棒。
从我的代码中可以看出,我没有在叠加层中设置Drawable,而是在另一个对象中进行外部操作,并怀疑这就是它破坏的原因!
目前我通过这样设置我的Drawable ......
public Drawable getRotatedIcon(String string) {
Drawable marker = null;
Double tempHeading = Double.valueOf(string);
long intHeading = Math.round(tempHeading / 10);
int resID = getResources().getIdentifier(
"icon_rotate_" + Long.toString(intHeading), "drawable",
"com.test.testapp");
marker = getResources().getDrawable(resID);
marker.setBounds(0, 0, marker.getIntrinsicWidth(),marker.getIntrinsicHeight());
return marker;
}
然后创建它我用这个......
if (sites != null){
sites.clearItems();
}else{
sites = new SitesOverlay();
}
for (int i = 0; i < getMainOverlayArray().size(); i++) {
tempOver = getMainOverlayArray().get(i);
tempOver.setMarker(getRotatedIcon(tempOver.getcourse()));
if (tempOver != null){
sites.addItem(tempOver);
}
}
sites.finishedLoading();
我的SitesOverlay课程......
private class SitesOverlay extends ItemizedOverlay<pfOverlayItem> {
private List<pfOverlayItem> items = new ArrayList<pfOverlayItem>();
private PopupPanel panel=new PopupPanel(R.layout.popup);
private MapLocation selectedMapLocation;
private static final int CIRCLERADIUS = 2;
private ArrayList<pfOverlayItem> mOverlays = new ArrayList<pfOverlayItem>();
public SitesOverlay() {
super(null);
populate();
}
public void finishedLoading(){
populate();
}
@Override
protected pfOverlayItem createItem(int i) {
return (items.get(i));
}
public void addItem(OverlayItem overlay) {
overlay.setMarker(boundCenter(overlay.getMarker(0)));
items.add((pfOverlayItem) overlay);
}
public void clearItems(){
runOnUiThread(new Runnable() {
public void run() {
items.clear();
myMapView.invalidate();
}
});
}
public void clear() {
mOverlays.clear();
myMapView.removeAllViews();
setLastFocusedIndex(-1);
populate();
}
@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
super.draw(canvas, mapView, false);
try {
if (getMainOverlayArray().size() != 0){
pfOverlayItem tempOver = null;
for (int i = 0; i < getMainOverlayArray().size(); i++) {
tempOver = getMainOverlayArray().get(i);
boolean isMatch = false;
//Log.i("Selected Name",selectedName);
if (tempOver.getTitle().equals(selectedName))
{
isMatch = true;
}
if (isMatch){
Projection projection = mapView.getProjection();
Point point = new Point();
projection.toPixels(tempOver.getPoint(), point);
Paint background = new Paint();
background.setColor(Color.WHITE);
background.setAlpha(150);
RectF rect = new RectF();
rect.set(point.x - 50, point.y +15,
point.x + 90, point.y + 50);
canvas.drawRoundRect(rect, 5, 5, background);
Paint text = new Paint();
text.setAntiAlias(true);
text.setColor(Color.BLUE);
text.setTextSize(14);
text.setTypeface(Typeface.MONOSPACE);
canvas.drawText(tempOver.getTitle() + " " + tempOver.getcallsign(), point.x -50 , point.y + 30, text);
canvas.drawText(tempOver.getdestination() + " " + tempOver.getdraft(), point.x -50 , point.y + 45, text);
}
}
}
}catch (Exception e){
Log.e("Error", "Problem drawing view", e);
e.printStackTrace();
}
}
@Override
protected boolean onTap(int i) {
pfOverlayItem item = getItem(i);
if (selectedName.equals(item.getTitle())){
try{
Intent myIntent = new Intent(TestApp.this, DetailActivity.class);
myIntent.putExtra( "int", i);
myIntent.putExtra( "string", selectedName );
PlaneFinderMain.this.startActivity(myIntent);
}catch (Exception e){
Log.e("Error", "Cannot launch", e);
}
}
currentadshex = item.getmmsi();
new GetRouteTask(item.getmmsi()).execute();
selectedItem = i;
selectedName = item.getTitle();
selectedPlanePoint = item.getPoint();
GeoPoint geo=item.getPoint();
Point pt=myMapView.getProjection().toPixels(geo, null);
View view=panel.getView();
((TextView)view.findViewById(R.id.reg)).setText(item.getTitle());
((TextView)view.findViewById(R.id.callsign)).setText(item.getcallsign());
((TextView)view.findViewById(R.id.dest)).setText(item.getdestination());
((TextView)view.findViewById(R.id.draft)).setText(item.getdraft());
return (true);
}
@Override
public boolean onTouchEvent(MotionEvent event, MapView mapView) {
if (event.getAction() == MotionEvent.ACTION_DOWN){
if (selectedPlanePoint != null){
Projection projection = mapView.getProjection();
Point point = new Point();
projection.toPixels(selectedPlanePoint, point);
Point pointHit = new Point();
pointHit.x=(int)event.getX();
pointHit.y=(int)event.getY();
if ((point.x - pointHit.x) >-100 && (point.x - pointHit.x) <70 && (point.y - pointHit.y) < -25 && (point.y - pointHit.y) > -95){
try{
Intent myIntent = new Intent(TestApp.this, DetailActivity.class);
myIntent.putExtra( "int", selectedItem);
myIntent.putExtra( "string", selectedName );
TestApp.this.startActivity(myIntent);
}catch (Exception e){
Log.e("Error", "Cannot launch", e);
}
}else{
}
}
}
return false;
}
@Override
public int size() {
return (items.size());
}
public void addOverlay(OverlayItem o){
setLastFocusedIndex(-1);
populate();
}
}
答案 0 :(得分:6)
似乎自然的API选择RotateDrawable
是脑死亡,因为你只能从膨胀的布局中使用它。我已将问题中引用的Mark Murphy代码改编为以下活动,该活动显示纽约标记旋转,使用替代RotateDrawable以更灵活的方式包装包含的drawable:
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);
}
}
}
有任何问题,请随时提出。 : - )
答案 1 :(得分:0)
在那种情况下,李建议你试试AnimationDrawable
AnimationDrawable frameAnimation =
(AnimationDrawable) getResources().getDrawable(R.drawable.spin_animationm);
修改强> 在此期间,我发现了另一个有用的帖子“moving-icons-on-a-android-mapview”,建议在onDraw()中使用计时器线程。
希望有所帮助。