출처 : http://bench87.tistory.com/38

외국사이트에서 퍼왔습니다.

 
스샷에 보이듯이 말풍선만 뛰울수 있습니다...

소스는 자꾸 안된다는 분이 많아서 제가 되도록 살짝 고쳤습니다..

 

Android MapView Balloons

This project provides an easy way to annotate map overlay items with a simple information balloon when using the Android Maps external library (com.google.android.maps). It consists of BalloonOverlayView, a view representing the balloon that is displayed over your MapView andBalloonItemizedOverlay, an abstract extension of ItemizedOverlay.

The presentation of the balloons was mostly reverse engineered from Google's Places Directory application.

Usage

Create a subclass of BalloonItemizedOverlay in the same way you would do for the base ItemizedOverlay class. Rather than overriding onTap()(which is already implemented and final in the subclass to invoke the balloon view display for each item tap), you override onBalloonTap() to handle a screen tap event on the balloon itself.

The data displayed in each balloon is mapped to the title and snippet arguments you provide to the constructor of each OverlayItem.

The repository contains a working sample application project which fully demonstrates its usage.

Implementation

As of version 1.1, android-mapviewballoons is an Android Library project. Refer to 'Referencing a library project from an application' in this document for instructions on how to include it in your own Android project. Ensure you have the latest Android SDK, tools and Eclipse plugin installed.

Whats Missing?

  • Custom balloon layouts and data mappings
  • Long press support
  • Trackball support (not tested)
  • Focus events (not tested)

The code in this project is licensed under the Apache Software License 2.0.


Copyright (c) 2010 readyState Software Ltd.

프로젝트파일 구조입니다..참고해서 만들어주세요..ㅎㅎ



myMpa.java

01 /***
02  * Copyright (c) 2010 readyState Software Ltd
03  
04  * Licensed under the Apache License, Version 2.0 (the "License"); you may
05  * not use this file except in compliance with the License. You may obtain
06  * a copy of the License at
08  * Unless required by applicable law or agreed to in writing, software
09  * distributed under the License is distributed on an "AS IS" BASIS,
10  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  * See the License for the specific language governing permissions and
12  * limitations under the License.
13  
14  */
15   
16 package mapviewballoons.example;
17   
18 import java.util.List;
19   
20 import android.graphics.drawable.Drawable;
21 import android.os.Bundle;
22   
23 import com.google.android.maps.GeoPoint;
24 import com.google.android.maps.MapActivity;
25 import com.google.android.maps.MapController;
26 import com.google.android.maps.MapView;
27 import com.google.android.maps.Overlay;
28 import com.google.android.maps.OverlayItem;
29   
30 public class MyMap extends MapActivity {
31   
32     MapView mapView;
33     List<OVERLAY> mapOverlays;
34     Drawable drawable;
35     Drawable drawable2;
36     MyItemizedOverlay itemizedOverlay;
37     MyItemizedOverlay itemizedOverlay2;
38       
39     @Override
40     public void onCreate(Bundle savedInstanceState) {
41           
42         super.onCreate(savedInstanceState);
43         setContentView(R.layout.main);
44           
45         mapView = (MapView) findViewById(R.id.mapview);
46         mapView.setBuiltInZoomControls(true);
47           
48         mapOverlays = mapView.getOverlays();
49           
50         // first overlay
51         drawable = getResources().getDrawable(R.drawable.marker);
52         itemizedOverlay = new MyItemizedOverlay(drawable, mapView);
53           
54         GeoPoint point = new GeoPoint((int)(51.5174723*1E6),(int)(-0.0899537*1E6));
55         OverlayItem overlayItem = new OverlayItem(point, "Tomorrow Never Dies (1997)"
56                 "(M gives Bond his mission in Daimler car)");
57         itemizedOverlay.addOverlay(overlayItem);
58           
59         GeoPoint point2 = new GeoPoint((int)(51.515259*1E6),(int)(-0.086623*1E6));
60         OverlayItem overlayItem2 = new OverlayItem(point2, "GoldenEye (1995)"
61                 "(Interiors Russian defence ministry council chambers in St Petersburg)");      
62         itemizedOverlay.addOverlay(overlayItem2);
63           
64         mapOverlays.add(itemizedOverlay);
65           
66         // second overlay
67         drawable2 = getResources().getDrawable(R.drawable.marker2);
68         itemizedOverlay2 = new MyItemizedOverlay(drawable2, mapView);
69           
70         GeoPoint point3 = new GeoPoint((int)(51.513329*1E6),(int)(-0.08896*1E6));
71         OverlayItem overlayItem3 = new OverlayItem(point3, "Sliding Doors (1998)"
72                 "(interiors)");
73         itemizedOverlay2.addOverlay(overlayItem3);
74           
75         GeoPoint point4 = new GeoPoint((int)(51.51738*1E6),(int)(-0.08186*1E6));
76         OverlayItem overlayItem4 = new OverlayItem(point4, "Mission: Impossible (1996)"
77                 "(Ethan & Jim cafe meeting)");      
78         itemizedOverlay2.addOverlay(overlayItem4);
79           
80         mapOverlays.add(itemizedOverlay2);
81           
82         final MapController mc = mapView.getController();
83         mc.animateTo(point2);
84         mc.setZoom(16);
85           
86     }
87       
88     @Override
89     protected boolean isRouteDisplayed() {
90         return false;
91     }
92   
93 }
94 </OVERLAY>
MyItemizedOverlay.java




MyItemizedOverlay.java
01 /***
02  * Copyright (c) 2010 readyState Software Ltd
03  
04  * Licensed under the Apache License, Version 2.0 (the "License"); you may
05  * not use this file except in compliance with the License. You may obtain
06  * a copy of the License at
08  * Unless required by applicable law or agreed to in writing, software
09  * distributed under the License is distributed on an "AS IS" BASIS,
10  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  * See the License for the specific language governing permissions and
12  * limitations under the License.
13  
14  */
15   
16 package mapviewballoons.example;
17   
18 import java.util.ArrayList;
19   
20 import android.content.Context;
21 import android.graphics.drawable.Drawable;
22 import android.widget.Toast;
23   
24 import com.google.android.maps.MapView;
25 import com.google.android.maps.OverlayItem;
26   
27   
28 public class MyItemizedOverlay extends BalloonItemizedOverlay<OVERLAYITEM> {
29   
30     private ArrayList<OVERLAYITEM> m_overlays = new ArrayList<OVERLAYITEM>();
31     private Context c;
32       
33     public MyItemizedOverlay(Drawable defaultMarker, MapView mapView) {
34         super(boundCenter(defaultMarker), mapView);
35         c = mapView.getContext();
36     }
37   
38     public void addOverlay(OverlayItem overlay) {
39         m_overlays.add(overlay);
40         populate();
41     }
42   
43     @Override
44     protected OverlayItem createItem(int i) {
45         return m_overlays.get(i);
46     }
47   
48     @Override
49     public int size() {
50         return m_overlays.size();
51     }
52   
53     @Override
54     protected boolean onBalloonTap(int index) {
55         Toast.makeText(c, "onBalloonTap for overlay index " + index,
56                 Toast.LENGTH_LONG).show();
57         return true;
58     }
59       
60 }
61 </OVERLAYITEM></OVERLAYITEM></OVERLAYITEM>

BalloonOverlayView.java

001 /***
002  * Copyright (c) 2010 readyState Software Ltd
003  
004  * Licensed under the Apache License, Version 2.0 (the "License"); you may
005  * not use this file except in compliance with the License. You may obtain
006  * a copy of the License at
008  * Unless required by applicable law or agreed to in writing, software
009  * distributed under the License is distributed on an "AS IS" BASIS,
010  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011  * See the License for the specific language governing permissions and
012  * limitations under the License.
013  
014  */
015   
016 package mapviewballoons.example;
017   
018 import android.content.Context;
019 import android.view.Gravity;
020 import android.view.LayoutInflater;
021 import android.view.View;
022 import android.widget.FrameLayout;
023 import android.widget.ImageView;
024 import android.widget.LinearLayout;
025 import android.widget.TextView;
026   
027 import com.google.android.maps.OverlayItem;
028   
029 /**
030  * A view representing a MapView marker information balloon.
031  * <P>
032  * This class has a number of Android resource dependencies:
033  * </P>
034 <UL>
035  * <LI>drawable/balloon_overlay_bg_selector.xml</LI>
036  * <LI>drawable/balloon_overlay_close.png</LI>
037  * <LI>drawable/balloon_overlay_focused.9.png</LI>
038  * <LI>drawable/balloon_overlay_unfocused.9.png</LI>
039  * <LI>layout/balloon_map_overlay.xml</LI>
040  * </UL>
041  * <P></P>
042  
043  * @author Jeff Gilfelt
044  *
045  */
046 public class BalloonOverlayView extends FrameLayout {
047   
048     private LinearLayout layout;
049     private TextView title;
050     private TextView snippet;
051   
052     /**
053      * Create a new BalloonOverlayView.
054      
055      * @param context - The activity context.
056      * @param balloonBottomOffset - The bottom padding (in pixels) to be applied
057      * when rendering this view.
058      */
059     public BalloonOverlayView(Context context, int balloonBottomOffset) {
060   
061         super(context);
062   
063         setPadding(10, 0, 10, balloonBottomOffset);
064         layout = new LinearLayout(context);
065         layout.setVisibility(VISIBLE);
066   
067         LayoutInflater inflater = (LayoutInflater) context
068                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
069         View v = inflater.inflate(R.layout.balloon_overlay, layout);
070         title = (TextView) v.findViewById(R.id.balloon_item_title);
071         snippet = (TextView) v.findViewById(R.id.balloon_item_snippet);
072   
073         ImageView close = (ImageView) v.findViewById(R.id.close_img_button);
074         close.setOnClickListener(new OnClickListener() {
075             public void onClick(View v) {
076                 layout.setVisibility(GONE);
077             }
078         });
079   
080         FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
081                 LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
082         params.gravity = Gravity.NO_GRAVITY;
083   
084         addView(layout, params);
085   
086     }
087       
088     /**
089      * Sets the view data from a given overlay item.
090      
091      * @param item - The overlay item containing the relevant view data 
092      * (title and snippet). 
093      */
094     public void setData(OverlayItem item) {
095           
096         layout.setVisibility(VISIBLE);
097         if (item.getTitle() != null) {
098             title.setVisibility(VISIBLE);
099             title.setText(item.getTitle());
100         } else {
101             title.setVisibility(GONE);
102         }
103         if (item.getSnippet() != null) {
104             snippet.setVisibility(VISIBLE);
105             snippet.setText(item.getSnippet());
106         } else {
107             snippet.setVisibility(GONE);
108         }
109           
110     }
111   
112 }
BalloonItemizedOverlay.java

001 /***
002  * Copyright (c) 2010 readyState Software Ltd
003  
004  * Licensed under the Apache License, Version 2.0 (the "License"); you may
005  * not use this file except in compliance with the License. You may obtain
006  * a copy of the License at
008  * Unless required by applicable law or agreed to in writing, software
009  * distributed under the License is distributed on an "AS IS" BASIS,
010  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011  * See the License for the specific language governing permissions and
012  * limitations under the License.
013  
014  */
015   
016 package mapviewballoons.example;
017   
018   
019   
020 import java.lang.reflect.Method; 
021 import java.util.List;
022   
023 import android.graphics.drawable.Drawable;
024 import android.util.Log;
025 import android.view.MotionEvent;
026 import android.view.View;
027 import android.view.View.OnTouchListener;
028 import android.view.ViewGroup.LayoutParams;
029   
030 import com.google.android.maps.GeoPoint;
031 import com.google.android.maps.ItemizedOverlay;
032 import com.google.android.maps.MapController;
033 import com.google.android.maps.MapView;
034 import com.google.android.maps.Overlay;
035 import com.google.android.maps.OverlayItem;
036   
037 /**
038  * An abstract extension of ItemizedOverlay for displaying an information balloon
039  * upon screen-tap of each marker overlay.
040  
041  * @author Jeff Gilfelt
042  */
043 public abstract class BalloonItemizedOverlay<ITEM> extends ItemizedOverlay<OVERLAYITEM> {
044   
045     private MapView mapView;
046     private BalloonOverlayView balloonView;
047     private View clickRegion;
048     private int viewOffset;
049     final MapController mc;
050       
051       
052     public BalloonItemizedOverlay(Drawable defaultMarker, MapView mapView) {
053         super(defaultMarker);
054         this.mapView = mapView;
055         viewOffset = 0;
056         mc = mapView.getController();
057     }
058       
059       
060     public void setBalloonBottomOffset(int pixels) {
061         viewOffset = pixels;
062     }
063       
064   
065     protected boolean onBalloonTap(int index) {
066         return false;
067     }
068   
069   
070     @Override
071     protected final boolean onTap(int index) {
072           
073         boolean isRecycled;
074         final int thisIndex;
075         GeoPoint point;
076           
077         thisIndex = index;
078         point = createItem(index).getPoint();
079           
080         if (balloonView == null) {
081             balloonView = new BalloonOverlayView(mapView.getContext(), viewOffset);
082             clickRegion = (View) balloonView.findViewById(R.id.balloon_inner_layout);
083             isRecycled = false;
084         } else {
085             isRecycled = true;
086         }
087       
088         balloonView.setVisibility(View.GONE);
089           
090         List<OVERLAY> mapOverlays = mapView.getOverlays();
091         if (mapOverlays.size() > 1) {
092             hideOtherBalloons(mapOverlays);
093         }
094           
095         balloonView.setData(createItem(index));
096           
097         MapView.LayoutParams params = new MapView.LayoutParams(
098                 LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, point,
099                 MapView.LayoutParams.BOTTOM_CENTER);
100         params.mode = MapView.LayoutParams.MODE_MAP;
101           
102         setBalloonTouchListener(thisIndex);
103           
104         balloonView.setVisibility(View.VISIBLE);
105   
106         if (isRecycled) {
107             balloonView.setLayoutParams(params);
108         } else {
109             mapView.addView(balloonView, params);
110         }
111           
112         mc.animateTo(point);
113           
114         return true;
115     }
116       
117     /**
118      * Sets the visibility of this overlay's balloon view to GONE. 
119      */
120     private void hideBalloon() {
121         if (balloonView != null) {
122             balloonView.setVisibility(View.GONE);
123         }
124     }
125       
126     /**
127      * Hides the balloon view for any other BalloonItemizedOverlay instances
128      * that might be present on the MapView.
129      
130      * @param overlays - list of overlays (including this) on the MapView.
131      */
132     private void hideOtherBalloons(List<OVERLAY> overlays) {
133           
134         for (Overlay overlay : overlays) {
135             if (overlay instanceof BalloonItemizedOverlay<!--?--> && overlay != this) {
136                 ((BalloonItemizedOverlay<!--?-->) overlay).hideBalloon();
137             }
138         }
139           
140     }
141       
142     /**
143      * Sets the onTouchListener for the balloon being displayed, calling the
144      * overridden onBalloonTap if implemented.
145      
146      * @param thisIndex - The index of the item whose balloon is tapped.
147      */
148     private void setBalloonTouchListener(final int thisIndex) {
149           
150         try {
151             @SuppressWarnings("unused")
152             Method m = this.getClass().getDeclaredMethod("onBalloonTap", int.class);
153               
154             clickRegion.setOnTouchListener(new OnTouchListener() {
155                 public boolean onTouch(View v, MotionEvent event) {
156                       
157                     View l =  ((View) v.getParent()).findViewById(R.id.balloon_main_layout);
158                     Drawable d = l.getBackground();
159                       
160                     if (event.getAction() == MotionEvent.ACTION_DOWN) {
161                         int[] states = {android.R.attr.state_pressed};
162                         if (d.setState(states)) {
163                             d.invalidateSelf();
164                         }
165                         return true;
166                     } else if (event.getAction() == MotionEvent.ACTION_UP) {
167                         int newStates[] = {};
168                         if (d.setState(newStates)) {
169                             d.invalidateSelf();
170                         }
171                         // call overridden method
172                         onBalloonTap(thisIndex);
173                         return true;
174                     } else {
175                         return false;
176                     }
177                       
178                 }
179             });
180               
181         } catch (SecurityException e) {
182             Log.e("BalloonItemizedOverlay", "setBalloonTouchListener reflection SecurityException");
183             return;
184         } catch (NoSuchMethodException e) {
185             // method not overridden - do nothing
186             return;
187         }
188   
189     }
190       
191 }
192 </OVERLAY></OVERLAY></OVERLAYITEM></ITEM>




balloon_overlay.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content"
    android:orientation="horizontal" 
    android:paddingBottom="35dip"
    android:paddingLeft="10dip" 
    android:minWidth="200dip" 
    android:id="@+id/balloon_main_layout"
    android:background="@drawable/balloon_overlay_bg_selector" 
    android:paddingTop="0dip"
    android:paddingRight="0dip">
   <LinearLayout 

       android:layout_width="wrap_content" 

       android:layout_height="wrap_content"

       android:orientation="vertical" 

       android:layout_weight="1"

       android:paddingTop="10dip" 

       android:id="@+id/balloon_inner_layout">

       <TextView android:layout_height="wrap_content"

           android:layout_width="fill_parent" 

           android:id="@+id/balloon_item_title"

           android:text="balloon_item_title" 

           android:textSize="16dip"

           android:textColor="#FF000000"></TextView>

       <TextView android:layout_height="wrap_content"

           android:layout_width="fill_parent" 

           android:id="@+id/balloon_item_snippet"

           android:text="balloon_item_snippet" 

           android:textSize="12dip"></TextView>

   </LinearLayout>

   

     <ImageView android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        android:src="@drawable/balloon_overlay_close"
        android:id="@+id/close_img_button" 
        android:paddingLeft="10dip"
        android:paddingBottom="10dip" 
        android:paddingRight="8dip"
        android:paddingTop="8dip"></ImageView>
</LinearLayout>








main.xml

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/mainlayout" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <com.google.android.maps.MapView android:id="@+id/mapview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:clickable="true" android:apiKey="YOUR_API_KEY" /> </RelativeLayout>






 
졸업장품으로 간단하게 어플을 만들었는데 그중 하나가 이 소스를 이용하여 일본 나고야 관광어플을 만들었습니다.
아래 스샷은 위에 소스를 이용하여 사진도 넣을수 있게 변경한것입니다..ㅎㅎ
이런식으로 꾸미면 지역소개 어플마들때 훨신 더 이쁘게 만들어지더라구요.. 










지도위에 찍히는 마커도 저희가 바꿔봤습니다.
 






말풍선이 두개 필요하여 위에 소스를 이용하여 수정하였습니다..
파란색 마커는 상세 페이지가 없고
금색마커는 상세페이지가 있는데 클릭시 index값을 공유하는 바람에
클릭이벤트 처리에 한계를 느껴서 수정하게 되었습니다.(무슨말인지..ㅋㅋㅋ) 







말풍선을 클릭했을시 상세페이지로 가게 됩니다..ㅎㅎ
 



저 위 소스를 이용하여 더 많은것도 할수 있겠죠?
다음에는 구글맵으로 길찾기 기능을 소개해볼려고합니다.


+ Recent posts