轉載註明出處: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