一種Android中地圖縮放Marker不跟隨縮放的方法

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

canvas保存、恢復操作

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

發佈了17 篇原創文章 · 獲贊 1 · 訪問量 5870
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章