외국사이트에서 퍼왔습니다.
스샷에 보이듯이 말풍선만 뛰울수 있습니다...
소스는 자꾸 안된다는 분이 많아서 제가 되도록 살짝 고쳤습니다..
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
02 |
* Copyright (c) 2010 readyState Software Ltd |
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. |
16 |
package mapviewballoons.example; |
18 |
import java.util.List; |
20 |
import android.graphics.drawable.Drawable; |
21 |
import android.os.Bundle; |
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; |
30 |
public class MyMap extends MapActivity { |
33 |
List<OVERLAY> mapOverlays; |
36 |
MyItemizedOverlay itemizedOverlay; |
37 |
MyItemizedOverlay itemizedOverlay2; |
40 |
public void onCreate(Bundle savedInstanceState) { |
42 |
super .onCreate(savedInstanceState); |
43 |
setContentView(R.layout.main); |
45 |
mapView = (MapView) findViewById(R.id.mapview); |
46 |
mapView.setBuiltInZoomControls( true ); |
48 |
mapOverlays = mapView.getOverlays(); |
51 |
drawable = getResources().getDrawable(R.drawable.marker); |
52 |
itemizedOverlay = new MyItemizedOverlay(drawable, mapView); |
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); |
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); |
64 |
mapOverlays.add(itemizedOverlay); |
67 |
drawable2 = getResources().getDrawable(R.drawable.marker2); |
68 |
itemizedOverlay2 = new MyItemizedOverlay(drawable2, mapView); |
70 |
GeoPoint point3 = new GeoPoint(( int )( 51.513329 *1E6),( int )(- 0.08896 *1E6)); |
71 |
OverlayItem overlayItem3 = new OverlayItem(point3, "Sliding Doors (1998)" , |
73 |
itemizedOverlay2.addOverlay(overlayItem3); |
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); |
80 |
mapOverlays.add(itemizedOverlay2); |
82 |
final MapController mc = mapView.getController(); |
89 |
protected boolean isRouteDisplayed() { |
MyItemizedOverlay.java
MyItemizedOverlay.java
02 |
* Copyright (c) 2010 readyState Software Ltd |
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. |
16 |
package mapviewballoons.example; |
18 |
import java.util.ArrayList; |
20 |
import android.content.Context; |
21 |
import android.graphics.drawable.Drawable; |
22 |
import android.widget.Toast; |
24 |
import com.google.android.maps.MapView; |
25 |
import com.google.android.maps.OverlayItem; |
28 |
public class MyItemizedOverlay extends BalloonItemizedOverlay<OVERLAYITEM> { |
30 |
private ArrayList<OVERLAYITEM> m_overlays = new ArrayList<OVERLAYITEM>(); |
33 |
public MyItemizedOverlay(Drawable defaultMarker, MapView mapView) { |
34 |
super (boundCenter(defaultMarker), mapView); |
35 |
c = mapView.getContext(); |
38 |
public void addOverlay(OverlayItem overlay) { |
39 |
m_overlays.add(overlay); |
44 |
protected OverlayItem createItem( int i) { |
45 |
return m_overlays.get(i); |
50 |
return m_overlays.size(); |
54 |
protected boolean onBalloonTap( int index) { |
55 |
Toast.makeText(c, "onBalloonTap for overlay index " + index, |
56 |
Toast.LENGTH_LONG).show(); |
61 |
</OVERLAYITEM></OVERLAYITEM></OVERLAYITEM> |
BalloonOverlayView.java
002 |
* Copyright (c) 2010 readyState Software Ltd |
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. |
016 |
package mapviewballoons.example; |
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; |
027 |
import com.google.android.maps.OverlayItem; |
030 |
* A view representing a MapView marker information balloon. |
032 |
* This class has a number of Android resource dependencies: |
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> |
043 |
* @author Jeff Gilfelt |
046 |
public class BalloonOverlayView extends FrameLayout { |
048 |
private LinearLayout layout; |
049 |
private TextView title; |
050 |
private TextView snippet; |
053 |
* Create a new BalloonOverlayView. |
055 |
* @param context - The activity context. |
056 |
* @param balloonBottomOffset - The bottom padding (in pixels) to be applied |
057 |
* when rendering this view. |
059 |
public BalloonOverlayView(Context context, int balloonBottomOffset) { |
063 |
setPadding( 10 , 0 , 10 , balloonBottomOffset); |
064 |
layout = new LinearLayout(context); |
065 |
layout.setVisibility(VISIBLE); |
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); |
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); |
080 |
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( |
081 |
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); |
082 |
params.gravity = Gravity.NO_GRAVITY; |
084 |
addView(layout, params); |
089 |
* Sets the view data from a given overlay item. |
091 |
* @param item - The overlay item containing the relevant view data |
092 |
* (title and snippet). |
094 |
public void setData(OverlayItem item) { |
096 |
layout.setVisibility(VISIBLE); |
097 |
if (item.getTitle() != null ) { |
098 |
title.setVisibility(VISIBLE); |
099 |
title.setText(item.getTitle()); |
101 |
title.setVisibility(GONE); |
103 |
if (item.getSnippet() != null ) { |
104 |
snippet.setVisibility(VISIBLE); |
105 |
snippet.setText(item.getSnippet()); |
107 |
snippet.setVisibility(GONE); |
BalloonItemizedOverlay.java
002 |
* Copyright (c) 2010 readyState Software Ltd |
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. |
016 |
package mapviewballoons.example; |
020 |
import java.lang.reflect.Method; |
021 |
import java.util.List; |
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; |
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; |
038 |
* An abstract extension of ItemizedOverlay for displaying an information balloon |
039 |
* upon screen-tap of each marker overlay. |
041 |
* @author Jeff Gilfelt |
043 |
public abstract class BalloonItemizedOverlay<ITEM> extends ItemizedOverlay<OVERLAYITEM> { |
045 |
private MapView mapView; |
046 |
private BalloonOverlayView balloonView; |
047 |
private View clickRegion; |
048 |
private int viewOffset; |
049 |
final MapController mc; |
052 |
public BalloonItemizedOverlay(Drawable defaultMarker, MapView mapView) { |
053 |
super (defaultMarker); |
054 |
this .mapView = mapView; |
056 |
mc = mapView.getController(); |
060 |
public void setBalloonBottomOffset( int pixels) { |
065 |
protected boolean onBalloonTap( int index) { |
071 |
protected final boolean onTap( int index) { |
078 |
point = createItem(index).getPoint(); |
080 |
if (balloonView == null ) { |
081 |
balloonView = new BalloonOverlayView(mapView.getContext(), viewOffset); |
082 |
clickRegion = (View) balloonView.findViewById(R.id.balloon_inner_layout); |
088 |
balloonView.setVisibility(View.GONE); |
090 |
List<OVERLAY> mapOverlays = mapView.getOverlays(); |
091 |
if (mapOverlays.size() > 1 ) { |
092 |
hideOtherBalloons(mapOverlays); |
095 |
balloonView.setData(createItem(index)); |
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; |
102 |
setBalloonTouchListener(thisIndex); |
104 |
balloonView.setVisibility(View.VISIBLE); |
107 |
balloonView.setLayoutParams(params); |
109 |
mapView.addView(balloonView, params); |
118 |
* Sets the visibility of this overlay's balloon view to GONE. |
120 |
private void hideBalloon() { |
121 |
if (balloonView != null ) { |
122 |
balloonView.setVisibility(View.GONE); |
127 |
* Hides the balloon view for any other BalloonItemizedOverlay instances |
128 |
* that might be present on the MapView. |
130 |
* @param overlays - list of overlays (including this) on the MapView. |
132 |
private void hideOtherBalloons(List<OVERLAY> overlays) { |
134 |
for (Overlay overlay : overlays) { |
135 |
if (overlay instanceof BalloonItemizedOverlay<!--?--> && overlay != this ) { |
136 |
((BalloonItemizedOverlay<!--?-->) overlay).hideBalloon(); |
143 |
* Sets the onTouchListener for the balloon being displayed, calling the |
144 |
* overridden onBalloonTap if implemented. |
146 |
* @param thisIndex - The index of the item whose balloon is tapped. |
148 |
private void setBalloonTouchListener( final int thisIndex) { |
151 |
@SuppressWarnings ( "unused" ) |
152 |
Method m = this .getClass().getDeclaredMethod( "onBalloonTap" , int . class ); |
154 |
clickRegion.setOnTouchListener( new OnTouchListener() { |
155 |
public boolean onTouch(View v, MotionEvent event) { |
157 |
View l = ((View) v.getParent()).findViewById(R.id.balloon_main_layout); |
158 |
Drawable d = l.getBackground(); |
160 |
if (event.getAction() == MotionEvent.ACTION_DOWN) { |
161 |
int [] states = {android.R.attr.state_pressed}; |
162 |
if (d.setState(states)) { |
166 |
} else if (event.getAction() == MotionEvent.ACTION_UP) { |
167 |
int newStates[] = {}; |
168 |
if (d.setState(newStates)) { |
172 |
onBalloonTap(thisIndex); |
181 |
} catch (SecurityException e) { |
182 |
Log.e( "BalloonItemizedOverlay" , "setBalloonTouchListener reflection SecurityException" ); |
184 |
} catch (NoSuchMethodException e) { |
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">
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: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>
<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값을 공유하는 바람에
클릭이벤트 처리에 한계를 느껴서 수정하게 되었습니다.(무슨말인지..ㅋㅋㅋ)
말풍선을 클릭했을시 상세페이지로 가게 됩니다..ㅎㅎ
저 위 소스를 이용하여 더 많은것도 할수 있겠죠?
다음에는 구글맵으로 길찾기 기능을 소개해볼려고합니다.