2011-01-29 2 views
0

Немного странный пост, как это я уже писал ранее, думал, что он был решен, но не сделал!ItemizedOverlay Поворот маркера и авария

У меня есть ситуация, когда мне нужно использовать пользовательский Drawable для каждого маркера, эффект, который мне нужен, - повернуть маркер на заданное количество градусов и, вероятно, пойдет не так.

В начале я пользуюсь отличным Creative Commons, так как это действительно работает и только ломается после моих дополнений!

https://github.com/commonsguy/cw-advandroid/tree/master/Maps/NooYawkAsync

предыдущий пост и коды здесь

Android Maps NullPointerException ItemizedOverlay

Если кто-нибудь могут порекомендовать более и более стабильный способ получить развернутую вытяжку и поставили меня на правильном пути, что бы будь велика.

Как вы можете видеть из моего кода, я не устанавливаю 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(); 
     } 



    } 

ответ

6

Кажется, что естественный выбор API, RotateDrawable, является braindead, в котором вы можете использовать его только из раздутого макета. Я адаптированный код Марка Мерфи ссылается на вопрос в следующей деятельности, которая показывает маркеры Нью-Йорк спиннинг, используя альтернативный RotateDrawable который оборачивает в Содержится вытяжке в более гибкой форме:

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); 
     } 
    } 

} 

Все вопросы, не стесняйтесь просить. :-)

+0

Это выглядит отлично, Рубен, и я думаю, что у него действительно есть пробег! Я полагаю, что лучший способ для каждого маркера иметь другой угол - передать дополнительный параметр в this.marker = new RotateDrawable (marker); ?? –

+1

О, точно. Я просто заставлял их поворачивать на 5 градусов каждый кадр в RotateDrawable.rotate(), чтобы показать, что это сработало ... вам не нужно сохранять эту функцию. Вы также можете потерять неиспользуемые поля mPivotX и mPivotY btw ... они не нужны. –

+0

ОК спасибо, я полагаю, я также вытащил run(), так как мне не нужно анимировать ротацию, это будет однократное вращение элемента, никакой анимации не потребуется вообще. –

0

В этом случае Ли я предлагаю вам попробовать на AnimationDrawable

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

EDIT: В то же время подошел еще один полезный пост «moving-icons-on-a-android-mapview», который предлагает использовать поток таймера в OnDraw().

Надеюсь, что это поможет.

+0

Но это для их оживления? Я хочу повернуть каждый на другое число градусов? –

+0

Ли для вращения вы можете использовать RotateDrawable, но я никогда не устанавливал его углы программным путем. – 100rabh

+0

Да, хорошо, я работаю с использованием более легкого метода, предварительно вращаясь, поэтому ОС не нужно. Он падает нечасто, но достаточно, чтобы раздражать пользователей, поэтому он должен быть чем-то маленьким. Что вы предлагаете, я пробовал, и он забивает процессор. –

 Смежные вопросы

  • Нет связанных вопросов^_^