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";
}
}
}
}
J'ai regardé ce depuis trop longtemps ... Quelle chose stupide manque-t-il? Aidez-moi!
ajoutez votre message logcat – Pavya
Revérifier que le XML est associé au même fichier java – Mangesh