2015-12-22 18 views
0

我试图覆盖谷歌地图上的比例尺,但findViewById()返回null并导致程序失败。我添加了两个textView,以确定我的布局中的所有视图是否都已损坏,但findViewById()会为其返回有效视图,并且还会为Google地图片段提供有效视图。我在Android Device Monitor中使用了层次结构查看器,并确定没有与ScaleBar视图关联的idAndroid 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"; 
      } 
     } 
    } 
} 

enter image description here

我已经看了这个太久...我错过了什么愚蠢的东西?帮帮我!

+0

添加您的logcat消息 – Pavya

+0

重新检查该XML与同一个Java文件 – Mangesh

回答

0

您只调用1参数构造函数(忽略xml属性)。 所以,这样更改代码:

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

谢谢你相关!无法通过树木看到森林。 –