最近自己在弄一个跟地图相关的android应用,想在地图中间增加一个十字架,在按下地位按钮时,地图上的点能与十字架对准。
在网上搜索了一下,这方面的文章比较少,有一篇文章《自定义十字架》(链接http://blog.csdn.net/bzy601638015/article/details/38800365),我试着按这位博主的文章去做,发现十字架与定位点有偏差。
后来发现是因为标题栏的高度,因为计算时,只是得到了状态栏的高度。参照《自定义十字架》这篇文章,再结合自己的实际应用,进行了修改。
1、先在res/values 目录下自定义一个View 的xml文件,名字为view_cross.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="CrossView"> <attr name="lineWidth" format="dimension"></attr> <attr name="lineLength" format="dimension"></attr> <attr name="lineColor" format="color"></attr> </declare-styleable> </resources>
其中,lineWidth 为线宽,lineLength为线长,lineColor为线的颜色。
2.在src的包下,建立一个名为CrossView的java文件
public class CrossView extends View{ private int mLength; private int mWidth; private int mColor; private Context mContext; private Paint mPaint; public CrossView(Context context) { super(context); // TODO Auto-generated constructor stub } public CrossView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); // TODO Auto-generated constructor stub } public CrossView(Context context, AttributeSet attrs) { super(context, attrs); this.mContext= context; TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CrossView); mLength = (int) ta.getDimension(R.styleable.CrossView_lineLength, 20); mWidth = (int) ta.getDimension(R.styleable.CrossView_lineWidth, 0); mColor = ta.getColor(R.styleable.CrossView_lineColor, 0); mPaint = new Paint(); mPaint.setColor(mColor); mPaint.setStrokeWidth(mWidth); mPaint.setAntiAlias(true); ta.recycle(); } protected void onDraw(Canvas canvas){ super.onDraw(canvas); DrawCrossView(canvas); } private void DrawCrossView(Canvas canvas) { // 获取屏幕的尺寸 DisplayMetrics dm = getResources().getDisplayMetrics(); int width = dm.widthPixels; int height = dm.heightPixels; // 获取状态栏的高度 Rect frame = new Rect(); getWindowVisibleDisplayFrame(frame); int statusBarHeight = frame.top; // 设置竖线的位置 int startX = width / 2; int startY = height / 2 - statusBarHeight/2 - mLength / 2; int stopX = startX; int stopY = startY + mLength; Log.i("ScreenHeight", height + ""); Log.i("ScreenWidth", width + ""); Log.i("statusBarHeight", statusBarHeight + ""); Log.i("startY", startY + ""); Log.i("stopY", stopY + ""); Log.i("mLength", mLength/2 + ""); canvas.drawLine(startX, startY, stopX, stopY, mPaint); // 设置横线的位置 startX = width / 2 - mLength / 2; startY = (height - statusBarHeight) / 2; stopX = startX + mLength; stopY = startY; Log.d("startX", startX + ""); canvas.drawLine(startX, startY, stopX, stopY, mPaint); } }
mWidth = (int) ta.getDimension(R.styleable.CrossView_lineWidth, 0); mColor = ta.getColor(R.styleable.CrossView_lineColor, 0);上下面的两个参数最后一位可以为0.
3、在地图界面加入CrossView
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:yxh="http://schemas.android.com/apk/res/com.yxh.googlemap" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.yxh.googlemap.MainActivity" > <fragment android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent" class="com.google.android.gms.maps.MapFragment" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/displayProjectName" android:layout_width="120dp" android:layout_height="wrap_content" android:lines="1" android:maxLength="10" android:text="@string/displayProjectName" android:textSize="8pt" /> <Button android:id="@+id/NormalMapButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="NormolView" android:text="@string/NromoMapButton" /> <Button android:id="@+id/SatelliteMapButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="Satellite" android:text="@string/SatelliteMapButton" /> </LinearLayout> <Button android:id="@+id/addMarker" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom" android:text="@string/addMarker" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center"> <com.yxh.googlemap.CrossView android:layout_width="wrap_content" android:layout_height="wrap_content" yxh:lineWidth="2dp" yxh:lineColor="#000000"/> </LinearLayout> </FrameLayout>
最后运行,发现有问题。如上图所示,十字架与定位点出现偏差。弄了好久才发现在《自定义十字架》的这篇文章中,没有标题栏的高度,所以,而我这里有标题栏。这才是出现偏差的原因。后来,我也在网上找了好多关于求标题栏高度的,用getWindow()的方式,但是,都不行。当然,如果哪位朋友可有解决方案的,希望能告诉我。
后来,我就觉得不要标题栏。就在AndroidManifest.xml中地图的Activity加入android:theme = "@android:style/Theme.NoTitleBar"
<!-- 启动地图界面 --> <activity android:name=".MapFragmentActivity" android:theme="@android:style/Theme.NoTitleBar"> </activity>
最后,十字架终于和定位点重合在一起了。