自定義開發氣球com.google.android.maps.Overlay
android的api中沒有直接提供氣球和信息窗口的控件的實現,所以時常要開發帶信息窗口的氣球實現類,這時需要自定義一個氣球overlay來繼com.google.android.maps.Overlay
類,overlay就是可以自定義繪制的覆蓋在地圖上面的一個層。下面是代碼:
package morgen.mstx; import java.util.ArrayList; import java.util.List; import android.view.MotionEvent; import com.google.android.maps.GeoPoint; import com.google.android.maps.MapView; import com.google.android.maps.Overlay; import com.google.android.maps.Projection; import android.graphics.*; class MyBallonOverlay extends Overlay{ final static int picWidth=20; //氣球圖的寬度 final static int picHeight=34; //氣球圖的高度 final static int arcR=8;//信息窗口的圓角半徑 static MyBallonOverlay currentBallon=null;//表示當前選中的氣球 String msg; boolean showWindow=false; GeoPoint gp;//此氣球對應的經緯度 public MyBallonOverlay(GeoPoint gp,String msg){ this.gp=gp; this.msg=msg; } public GeoPoint getGeoPoint(){//獲得該氣球的經緯度GeoPoint return gp; } @Override public boolean onTouchEvent(MotionEvent event, MapView mv) { if(currentBallon!=null&¤tBallon!=this){ //若當前氣球不為空且不是自己,什么都不做 return false; } if(event.getAction() == MotionEvent.ACTION_DOWN){ //若在氣球上按下則設置當前氣球為自己,且當前狀態為在氣球上 int x=(int)event.getX(); int y=(int)event.getY(); Point p= getPoint(mv); int xb=p.x-picWidth/2; int yb=p.y-picHeight; if(x>=xb&&x<xb+picWidth&&y>=yb&&y<yb+picHeight){ //若在自己這個氣球上按下則設置自己為當前氣球 currentBallon=this; return true; } } else if (event.getAction() == MotionEvent.ACTION_MOVE) { //移動事件返回當前氣球狀態 若當前在氣球上則返回true 屏蔽其他移動事件 return currentBallon!=null; } else if (event.getAction() == MotionEvent.ACTION_UP) { //獲取觸控筆位置 int x=(int)event.getX(); int y=(int)event.getY(); //獲取氣球在屏幕上的坐標范圍 Point p= getPoint(mv); int xb=p.x-picWidth/2; int yb=p.y-picHeight; if(currentBallon==this&&x>=xb&&x<xb+picWidth&&y>=yb&&y<yb+picHeight){ //若當前氣球為自己且在當前氣球上抬起觸控則顯示當前氣球內容 //顯示完內容后清空當前氣球 currentBallon=null; showWindow=!showWindow; List<Overlay> overlays = mv.getOverlays(); overlays.remove(this);//刪除此氣球再添加 overlays.add(this);//此氣球就位于最上面了 for(Overlay ol:overlays){//清除其他氣球的showWindow標記 if(ol instanceof MyBallonOverlay){ if(ol!=this){ ((MyBallonOverlay)ol).showWindow=false; } } } return true; } else if(currentBallon==this){ //若當前氣球為自己但抬起觸控不再自己上則清空氣球狀態并返回true currentBallon=null; return true; } } return false; } @Override public void draw(Canvas canvas, MapView mapView, boolean shadow) { //將經緯度翻譯成屏幕上的XY坐標 Point p= getPoint(mapView); //在坐標指定位置繪制氣球 canvas.drawBitmap(MainActivity.bitmap, p.x-picWidth/2, p.y-picHeight, null); if(showWindow){//如果showWindow為true則顯示信息窗口 drawWindow(canvas,p,160); } //調用父類繪制 super.draw(canvas, mapView, shadow); } public Point getPoint(MapView mapView){//將經緯度翻譯成屏幕上的XY坐標 Projection projettion = mapView.getProjection(); Point p = new Point(); projettion.toPixels(gp, p); return p; } public void drawWindow(Canvas canvas,Point p,int winWidth){//繪制信息窗口的方法 int charSize=15; int textSize=16; int leftRightPadding=2; //為信息分行 int lineWidth=winWidth-leftRightPadding*2;//每行的寬度 int lineCharCount=lineWidth/(charSize); //每行字符數 //掃描整個信息字符串分行 ArrayList<String> alRows=new ArrayList<String>(); String currentRow=""; for(int i=0;i<msg.length();i++){ char c=msg.charAt(i); if(c!='\n'){ currentRow=currentRow+c; } else{ if(currentRow.length()>0){ alRows.add(currentRow); } currentRow=""; } if(currentRow.length()==lineCharCount){ alRows.add(currentRow); currentRow=""; } } if(currentRow.length()>0){ alRows.add(currentRow); } int lineCount=alRows.size();//總行數 int winHeight=lineCount*(charSize)+2*arcR;//窗體高度 //創建paint對象 Paint paint=new Paint(); paint.setAntiAlias(true); paint.setTextSize(textSize); //繪制 信息窗體圓角矩形 paint.setARGB(255, 255,251,239); int x1=p.x-winWidth/2; int y1=p.y-picHeight-winHeight-1; int x2=x1+winWidth; int y2=y1+winHeight; RectF r=new RectF(x1,y1,x2,y2); canvas.drawRoundRect(r, arcR, arcR, paint); paint.setARGB(255,198,195,198); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(2); canvas.drawRoundRect(r, arcR, arcR, paint); //循環繪制每行文字 paint.setStrokeWidth(0); paint.setARGB(255, 10, 10, 10); int lineY=y1+arcR+charSize; for(String lineStr:alRows){ System.out.println("lineStr"+lineStr); for(int j=0;j<lineStr.length();j++){ String colChar=lineStr.charAt(j)+""; canvas.drawText(colChar, x1+leftRightPadding+j*charSize, lineY, paint); } lineY=lineY+charSize; } } }
上述的draw方法完成了在指定的未知繪制氣球圖片,并根據氣球信息窗口的標志值來決定是否調用drawWindow方法來繪制氣球對應的信息窗口。這個自定義的氣球可以服務于
大部分涉及到谷歌地圖的應用,我有很多應用的涉及到了這些代碼,很是實用。 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!