2015-12-22 1 views
0

Je tente de superposer une barre d'échelle sur une carte google mais findViewById() renvoie null et entraîne l'échec du programme. J'ai ajouté deux textView pour déterminer si toutes les vues dans ma mise en page étaient cassées mais findViewById() renvoie des vues valides pour elles et également une vue valide pour le fragment de carte google. J'ai utilisé la visionneuse de la hiérarchie dans le Device Monitor Android et a déterminé qu'il n'y a aucun id associé à la vue ScaleBar.Android findViewById renvoie null (aucun ID associé à la vue du visualiseur de la hiérarchie)

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_maps); 

    mTv1 = (TextView) findViewById(R.id.tv1); 
    mTv2 = (TextView) findViewById(R.id.tv2); 

    mScaleBar = (ScaleBar) findViewById(R.id.scale); 

    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); 
    mapFragment.getMapAsync(this); 
} 

Mon fichier de mise en page 'de activity_maps.xml':

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 

<fragment 
    android:id="@+id/map" 
    class="com.google.android.gms.maps.SupportMapFragment" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" /> 

<TextView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Text1" 
    android:id="@+id/tv1" 
    android:layout_alignParentTop="true" 
    android:layout_alignParentStart="true" /> 

<com.dbf.dirteditor.ScaleBar 
    android:id="@+id/scale" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" /> 

<TextView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Text2" 
    android:id="@+id/tv2" 
    android:layout_alignParentBottom="true" 
    android:layout_alignParentEnd="true" /> 
</RelativeLayout> 

ScaleBar.java

public class ScaleBar extends ImageView { 
    float mXOffset = 10; 
    float mYOffset = 10; 
    float mLineWidth = 3; 
    int mTextSize = 25; 

    boolean mIsImperial = false; 
    boolean mIsNautical = false; 

    boolean mIsLatitudeBar = true; 
    boolean mIsLongitudeBar = true; 

    private GoogleMap mMap = null; 

    float mXdpi; 
    float mYdpi; 

    public ScaleBar(Context context) { 
     super(context); 
     init_ScaleBar(context); 
    } 

    public ScaleBar(Context context, AttributeSet attrs) { 
     super(context); 
     init_ScaleBar(context); 
    } 

    public ScaleBar(Context context, AttributeSet attrs, int defStyle) { 
     super(context); 
     init_ScaleBar(context); 
    } 

    private void init_ScaleBar(Context context) { 
    } 

    public void setGoogleMap(Context context, GoogleMap map) { 
     mMap = map; 

     mXdpi = context.getResources().getDisplayMetrics().xdpi; 
     mYdpi = context.getResources().getDisplayMetrics().ydpi; 
    } 

    @Override 
    public void onDraw(Canvas canvas) { 
     if (mMap != null) { 
      canvas.save(); 
      drawScaleBarPicture(canvas); 
      canvas.restore(); 
     } 
    } 

    private void drawScaleBarPicture(Canvas canvas) { 
     // We want the scale bar to be as long as the closest round-number miles/kilometers 
     // to 1-inch at the latitude at the current center of the screen. 

     Projection projection = mMap.getProjection(); 

     if (projection == null) { 
      return; 
     } 

     final Paint barPaint = new Paint(); 
     barPaint.setColor(Color.BLACK); 
     barPaint.setAntiAlias(true); 
     barPaint.setStrokeWidth(mLineWidth); 

     final Paint textPaint = new Paint(); 
     textPaint.setColor(Color.BLACK); 
     textPaint.setAntiAlias(true); 
     textPaint.setTextSize(mTextSize); 

     drawXMetric(canvas, textPaint, barPaint); 

     drawYMetric(canvas, textPaint, barPaint); 
    } 

    private void drawXMetric(Canvas canvas, Paint textPaint, Paint barPaint) { 
     Projection projection = mMap.getProjection(); 

     if (projection != null) { 
      LatLng p1 = projection.fromScreenLocation(new Point((int) ((getWidth()/2) - (mXdpi/2)), getHeight()/2)); 
      LatLng p2 = projection.fromScreenLocation(new Point((int) ((getWidth()/2) + (mXdpi/2)), getHeight()/2)); 

      Location locationP1 = new Location("ScaleBar location p1"); 
      Location locationP2 = new Location("ScaleBar location p2"); 

      locationP1.setLatitude(p1.latitude); 
      locationP2.setLatitude(p2.latitude); 
      locationP1.setLongitude(p1.longitude); 
      locationP2.setLongitude(p2.longitude); 

      float xMetersPerInch = locationP1.distanceTo(locationP2); 

      if (mIsLatitudeBar) { 
       String xMsg = scaleBarLengthText(xMetersPerInch); 
       Rect xTextRect = new Rect(); 
       textPaint.getTextBounds(xMsg, 0, xMsg.length(), xTextRect); 

       int textSpacing = (int) (xTextRect.height()/5.0); 

       canvas.drawRect(mXOffset, mYOffset, mXOffset + mXdpi, mYOffset + mLineWidth, barPaint); 
       canvas.drawRect(mXOffset + mXdpi, mYOffset, mXOffset + mXdpi + mLineWidth, mYOffset + 
         xTextRect.height() + mLineWidth + textSpacing, barPaint); 

       if (!mIsLongitudeBar) { 
        canvas.drawRect(mXOffset, mYOffset, mXOffset + mLineWidth, mYOffset + 
          xTextRect.height() + mLineWidth + textSpacing, barPaint); 
       } 
       canvas.drawText(xMsg, (mXOffset + mXdpi/2 - xTextRect.width()/2), 
         (mYOffset + xTextRect.height() + mLineWidth + textSpacing), textPaint); 
      } 
     } 
    } 

    private void drawYMetric(Canvas canvas, Paint textPaint, Paint barPaint) { 
     Projection projection = mMap.getProjection(); 

     if (projection != null) { 
      Location locationP1 = new Location("ScaleBar location p1"); 
      Location locationP2 = new Location("ScaleBar location p2"); 

      LatLng p1 = projection.fromScreenLocation(new Point(getWidth()/2, 
        (int) ((getHeight()/2) - (mYdpi/2)))); 
      LatLng p2 = projection.fromScreenLocation(new Point(getWidth()/2, 
        (int) ((getHeight()/2) + (mYdpi/2)))); 

      locationP1.setLatitude(p1.latitude); 
      locationP2.setLatitude(p2.latitude); 
      locationP1.setLongitude(p1.longitude); 
      locationP2.setLongitude(p2.longitude); 

      float yMetersPerInch = locationP1.distanceTo(locationP2); 

      if (mIsLongitudeBar) { 
       String yMsg = scaleBarLengthText(yMetersPerInch); 
       Rect yTextRect = new Rect(); 
       textPaint.getTextBounds(yMsg, 0, yMsg.length(), yTextRect); 

       int textSpacing = (int) (yTextRect.height()/5.0); 

       canvas.drawRect(mXOffset, mYOffset, mXOffset + mLineWidth, mYOffset + mYdpi, barPaint); 
       canvas.drawRect(mXOffset, mYOffset + mYdpi, mXOffset + yTextRect.height() + 
         mLineWidth + textSpacing, mYOffset + mYdpi + mLineWidth, barPaint); 

       if (!mIsLatitudeBar) { 
        canvas.drawRect(mXOffset, mYOffset, mXOffset + yTextRect.height() + 
          mLineWidth + textSpacing, mYOffset + mLineWidth, barPaint); 
       } 

       float x = mXOffset + yTextRect.height() + mLineWidth + textSpacing; 
       float y = mYOffset + mYdpi/2 + yTextRect.width()/2; 

       canvas.rotate(-90, x, y); 
       canvas.drawText(yMsg, x, y + textSpacing, textPaint); 
      } 
     } 
    } 

    private String scaleBarLengthText(float meters) { 
     if (this.mIsImperial) { 
      if (meters >= 1609.344) { 
       return (meters/1609.344) + "mi"; 
      } else if (meters >= 1609.344/10) { 
       return ((meters/160.9344)/10.0) + "mi"; 
      } else { 
       return (meters * 3.2808399) + "ft"; 
      } 
     } else if (this.mIsNautical) { 
      if (meters >= 1852) { 
       return ((meters/1852)) + "nm"; 
      } else if (meters >= 1852/10) { 
       return (((meters/185.2))/10.0) + "nm"; 
      } else { 
       return ((meters * 3.2808399)) + "ft"; 
      } 
     } else { 
      if (meters >= 1000) { 
       return ((meters/1000)) + "km"; 
      } else if (meters > 100) { 
       return ((meters/100.0)/10.0) + "km"; 
      } else { 
       return meters + "m"; 
      } 
     } 
    } 
} 

enter image description here

J'ai regardé ce depuis trop longtemps ... Quelle chose stupide manque-t-il? Aidez-moi!

+0

ajoutez votre message logcat – Pavya

+0

Revérifier que le XML est associé au même fichier java – Mangesh

Répondre

0

Vous appelez uniquement le constructeur 1 paramètre (qui ignore les attributs xml). Donc, changer votre code de cette façon:

public ScaleBar(Context context) { 
    this(context,null); 
} 

public ScaleBar(Context context, AttributeSet attrs) { 
    this(context,attrs,0); 
} 

public ScaleBar(Context context, AttributeSet attrs, int defStyle) { 
    super(context,attrs,defStyle); 
    init_ScaleBar(context); 
} 
+0

Merci! Impossible de voir la forêt à travers les arbres. –