Last active
March 1, 2017 02:35
-
-
Save vincent1086/b7dc2b998eaaf2d8db5c847109cd5704 to your computer and use it in GitHub Desktop.
Google Map infoWindow child view click event (ps. InfoWindow -> Canvas)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//////////////////// | |
// 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