转载注明出处:https://blog.csdn.net/skysukai
1、背景
在地图应用中一般都会标记出一些位置,本文称为“marker”。用户经常会有放大、缩小地图的操作,而在地图缩放的过程当中,marker的大小是不会随着地图的缩放而变大或缩小:
两张图片给出了地图放大前和放大后的效果,里面红色框框就是marker。可以看到,marker是不随地图的缩放而变化的。
2、项目需求
在项目中,我也遇到了这样的需求,即marker不随地图的缩放而变化,需保持一致的大小。
那要做到地图缩放而上面的marker不跟随缩放应该如何实现呢?
3、canvas的缩放操作
Android给canvas提供了两个api接口,用以实现缩放操作:
public void scale (float sx, float sy)//定义了以原点(0,0)进行缩放以及x轴、y轴的缩放比例
public final void scale (float sx, float sy, float px, float py)//定义了以(px,py)进行缩放以及x轴、y轴的缩放比例
给出一小段示例demo:
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
//scale 缩放坐标系密度
Paint paint_green = generatePaint(Color.GREEN, Style.STROKE, 5);
Paint paint_red = generatePaint(Color.RED, Style.STROKE, 5);
Rect rect1 = new Rect(10,10,200,100);
canvas.drawRect(rect1, paint_green);
canvas.scale(0.5f, 1);
canvas.drawRect(rect1, paint_red);
}
这样即完成了一次缩放过程。
4、canvas保存、恢复操作
为什么canvas需要保存和恢复?在进行canvas有关的coding之前,有几条经验是需要知道的:
- 1、每次调用canvas.drawXXXX系列函数来绘图进,都会产生一个全新的Canvas画布。
- 2、如果在DrawXXX前,调用平移、旋转等函数来对Canvas进行了操作,那么这个操作是不可逆的!每次产生的画布的最新位置都是这些操作后的位置。)
- 3、在Canvas与屏幕合成时,超出屏幕范围的图像是不会显示出来的。
所以,每当进行一次canvas操作之后,建议调用canvas.save()
、canvas.restore()
两个方法来保存恢复画布。给出一小段实例demo:
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
canvas.drawColor(Color.RED);
//保存当前画布大小即整屏
canvas.save();
canvas.clipRect(new Rect(100, 100, 800, 800));
canvas.drawColor(Color.GREEN);
//恢复整屏画布
canvas.restore();
canvas.drawColor(Color.BLUE);
}
5、具体实现
有了知识储备之后,就可以来具体实现了。要实现地图缩放,而地图上的marker不跟随地图缩放,只需检测到缩放手势之后,对地图所在的bitmap进行缩放操作即可。有一点需要注意,Android绘制bitmap时,默认是从左上角开始绘制,要使marker绘制在定位点正中间的话,只需减去marker长宽的1/2即可。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float scale = getAllScale();//获取缩放比例
canvas.save(); //保存画布
canvas.scale(scale, scale); // 缩放画布
Bitmap bitmap = mMapViewBitmap;
canvas.drawBitmap(bitmap, 0, 0, null);//在缩放后的canvas上绘制地图
canvas.restore(); //恢复画布
Resources resource = getResources();
Bitmap orientation = BitmapFactory.decodeResource(resource, R.mipmap.nav).copy(Bitmap.Config.ARGB_8888, true);
//定位点坐标(mLocationX,mLocationY)
canvas.drawBitmap(orientation, (float) (mLocationX * scale - orientation.getWidth() / 2.0) ,
(float) (mLocationY * scale - orientation.getHeight() / 2.0), null);
}
这样,就做到了缩放地图时,地图上的marker不跟随地图缩放。网上还给出了另外一种思路,记录marker的坐标比例,根据坐标比例来绘制marker。感觉计算起来要稍微复杂一点,大家也可以参考
相关参考 https://www.2cto.com/kf/201804/740438.html
相关参考 https://blog.csdn.net/ausboyue/article/details/78267461