Android findViewById返回null(层次结构查看器show没有与视图关联的id)

时间:2015-12-22 05:16:49

标签: android findviewbyid

我正在尝试在Google地图上叠加比例尺,但findViewById ()返回null并导致程序失败。我添加了两个textView来确定我的布局中的所有视图是否都被破坏了,但是Device Monitor为它们返回了有效视图,还有一个google地图片段的有效视图。我在Android id中使用了层次结构查看器,并确定没有与ScaleBar视图关联的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); }

<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>

我的布局文件'activity_maps.xml':

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

ScaleBar.java

int a = Integer.parseInt(T1.getText());
int b = Integer.parseInt(T2.getText());
String s = "";

int i;
  if(a>b)
{
for(i=b;i<=a;i++)
{
 s = s + " " + i;
}

}
if(b>a)
{
for(i=a;i<=b;i++)
{
 s = s + " " + i;
}

}
jTextField3.setText(s);

enter image description here

我已经看了太久了......我错过了什么愚蠢的事情?救命啊!

1 个答案:

答案 0 :(得分: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);
}