Skip to content

Instantly share code, notes, and snippets.

@vincent1086
Last active March 1, 2017 02:35
Show Gist options
  • Save vincent1086/b7dc2b998eaaf2d8db5c847109cd5704 to your computer and use it in GitHub Desktop.
Save vincent1086/b7dc2b998eaaf2d8db5c847109cd5704 to your computer and use it in GitHub Desktop.
Google Map infoWindow child view click event (ps. InfoWindow -> Canvas)
////////////////////
// Layout xml file.
///////////////////
<com.example.widget.MapInfoWindowWrapper
android:id="@+id/map_wrapper"
android:layout_width="match_parent"
android:layout_height="350dp">
<MapView
android:id="@+id/mapview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.example.widget.MapInfoWindowWrapper>
/////////////////////////////////////////
// The layout wrapper contain a map view
/////////////////////////////////////////
public class MapInfoWindowWrapper extends RelativeLayout {
private final String TAG = "MapInfoWindowWrapper";
private GoogleMap mGoogleMap;
private Marker mMarker;
private View mInfoWindow;
private int mEdga = 0;
public MapInfoWindowWrapper(Context context) {
super(context);
}
public MapInfoWindowWrapper(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void init(View infoWindow, GoogleMap map, Marker marker){
mGoogleMap = map;
mMarker = marker;
mInfoWindow = infoWindow;
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.i(TAG, "dispatchTouchEvent: Hit!!");
boolean ret = false;
// Make sure that the infoWindow is shown and we have all the needed references
if (mMarker != null && mMarker.isInfoWindowShown() && mGoogleMap != null && mInfoWindow != null) {
// Get a marker position on the screen
Point point = mGoogleMap.getProjection().toScreenLocation(mMarker.getPosition());
// Make a copy of the MotionEvent and adjust it's location
// so it is relative to the infoWindow left top corner
MotionEvent copyEv = MotionEvent.obtain(ev);
copyEv.offsetLocation(
-point.x + (mInfoWindow.getWidth() / 2),
-point.y + mInfoWindow.getHeight() + mEdga);
// Dispatch the adjusted MotionEvent to the infoWindow
ret = mInfoWindow.dispatchTouchEvent(copyEv);
}
// If the infoWindow consumed the touch event, then just return true.
// Otherwise pass this event to the super class and return it's result
return ret || super.dispatchTouchEvent(ev);
}
// 1. default marker height
// 2. offset between the default InfoWindow bottom edge and it's content bottom edge
public void setEdge(int size){
mEdga = size;
}
private class MapInfoWindowChildTouchListener implements View.OnTouchListener{
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return false;
}
}
}
/////////////////////////
// initialize a map view
/////////////////////////
private void onLoadGoogleMap(Result result){
mMapCallback = new MapCallback(result);
mInfoWindow = new MapInfoWindow(getActivity());
mInfoWindow.setValue(result.content, new double[]{result.address_latitude, result.address_longitude});
mMapView.onCreate(new Bundle());
mMapView.onResume();
mMapView.getMapAsync(mMapCallback);
}
////////////////////////////
// Google Map ready callback
////////////////////////////
private class MapCallback implements OnMapReadyCallback, GoogleMap.OnMarkerClickListener {
private Result result;
public boolean initialized;
public MapCallback(Result result){
this.result = result;
}
public static Drawable drawableScale(Context context, Drawable drawable, float scaleFactor) {
if ((drawable == null) || !(drawable instanceof BitmapDrawable)) {
return drawable;
}
Bitmap b = ((BitmapDrawable) drawable).getBitmap();
int sizeX = Math.round(drawable.getIntrinsicWidth() * scaleFactor);
int sizeY = Math.round(drawable.getIntrinsicHeight() * scaleFactor);
Bitmap bitmapResized = Bitmap.createScaledBitmap(b, sizeX, sizeY, false);
drawable = new BitmapDrawable(context.getResources(), bitmapResized);
return drawable;
}
@Override
public void onMapReady(GoogleMap map) {
Log.i(TAG, "onMapReady");
mGoogleMap = map;
MapsInitializer.initialize(getActivity());
LatLng latLng = new LatLng(result.address_latitude, result.address_longitude);
map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
map.getUiSettings().setZoomControlsEnabled(true);
Drawable iconDrawable = getActivity().getResources().getDrawable(result.type == 1 ? R.mipmap.map_1_pin : R.mipmap.map_2_pin);
Drawable resizeDrawable = drawableScale(getActivity(), iconDrawable, 1.2f);
if (resizeDrawable != null) {
BitmapDrawable icon = (BitmapDrawable) resizeDrawable;
map.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 17.0f));
map.setInfoWindowAdapter(mInfoWindow);
map.setOnMarkerClickListener(this);
mMarker = map.addMarker(new MarkerOptions().position(latLng).title(result.content)
.icon(BitmapDescriptorFactory.fromBitmap(icon.getBitmap())));
mInfoWindow.moveCenter(mGoogleMap, mMarker, false);
initialized = true;
}
}
public void move(int type, double latitude, double longitude, String address, boolean animation){
LatLng latLng = new LatLng(latitude, longitude);
Drawable iconDrawable = getActivity().getResources().getDrawable(type == 1 ? R.mipmap.map_1_pin : R.mipmap.map_2_pin);
Drawable resizeDrawable = Utils.drawableScale(getActivity(), iconDrawable, 1.2f);
if (resizeDrawable != null) {
BitmapDrawable icon = (BitmapDrawable) resizeDrawable;
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 17.0f));
mGoogleMap.setInfoWindowAdapter(mInfoWindow);
mMarker = mGoogleMap.addMarker(new MarkerOptions().position(latLng).title(address)
.icon(BitmapDescriptorFactory.fromBitmap(icon.getBitmap())));
mInfoWindow.moveCenter(mGoogleMap, mMarker, animation);
}
}
@Override
public boolean onMarkerClick(Marker marker) {
mInfoWindow.moveCenter(mGoogleMap, marker, true);
return true;
}
}
////////////////////////////////////////////////
// Get Google Map infowindow layout
// Update info must use marker.showInfoWindow()
////////////////////////////////////////////////
private class MapInfoWindow implements GoogleMap.InfoWindowAdapter{
private LayoutInflater layoutInflater;
public String content;
public double[] latlong;
public void setValue(String content, double[] latlong){
this.content = content;
this.latlong = latlong;
}
@Override
public View getInfoWindow(Marker marker) {
final View view = layoutInflater.inflate(R.layout.map_window, null);
final TextView contentText = (TextView)view.findViewById(R.id.content);
final FrameLayout btn = (FrameLayout)view.findViewById(R.id.btn);
contentText.setText(content);
btn.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.i(TAG, "Click!!");
return false;
}
});
return view;
}
@Override
public View getInfoContents(Marker marker) {
return null;
}
private void center(GoogleMap map, Marker marker, boolean animation){
Projection projection = map.getProjection();
LatLng latLng = marker.getPosition();
Point point = projection.toScreenLocation(latLng);
LatLng newLatLng = projection.fromScreenLocation(new Point(point.x, point.y - Utils.convertToPx(getActivity(), 120)));
if(animation){
map.animateCamera(CameraUpdateFactory.newLatLng(newLatLng));
}else{
map.moveCamera(CameraUpdateFactory.newLatLng(newLatLng));
}
marker.showInfoWindow();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment