我試圖覆蓋谷歌地圖上的比例尺,但findViewById()
返回null並導致程序失敗。我添加了兩個textView,以確定我的佈局中的所有視圖是否都已損壞,但findViewById()
會爲其返回有效視圖,並且還會爲Google地圖片段提供有效視圖。我在Android Device Monitor
中使用了層次結構查看器,並確定沒有與ScaleBar視圖關聯的id
。Android findViewById返回null(層次結構查看器顯示沒有與視圖關聯的ID)
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);
}
我的佈局文件 '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";
}
}
}
}
我已經看了這個太久...我錯過了什麼愚蠢的東西?幫幫我!
添加您的logcat消息 – Pavya
重新檢查該XML與同一個Java文件 – Mangesh