I am using Xamarin to render map with pins in Android. I am able Load the map and show custom Info window for my app, but I want a button or a link inside my Info window which when clicked do some computation and start a new activity.
This is what I am looking for:
On click of links (link1 and link2) I would like to redirect user to new screen based on some value. My concern here is how can I get a click function for the links.
Also I want the Info Window to have rounded corners and have a pointer pointing to the pin.
Here is my code for above example:
Activity
public class MainActivity : Activity, IOnMapReadyCallback
{
private GoogleMap GMap;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
SetUpMap();
}
private void SetUpMap()
{
if (GMap == null)
{
FragmentManager.FindFragmentById<MapFragment>(Resource.Id.googlemap).GetMapAsync(this);
}
}
public void OnMapReady(GoogleMap googleMap)
{
this.GMap = googleMap;
GMap.UiSettings.ZoomControlsEnabled = true;
LatLng latlng = new LatLng(Convert.ToDouble(15.354942), Convert.ToDouble(73.929845));
MarkerOptions markerOpt = new MarkerOptions();
markerOpt.SetPosition(latlng).SetTitle("test")
.SetSnippet("test")
.SetIcon(BitmapDescriptorFactory.DefaultMarker(BitmapDescriptorFactory.HueOrange));
MapAdapter adapter = new MapAdapter(this);
GMap.SetInfoWindowAdapter(adapter);
GMap.AddMarker(markerOpt).ShowInfoWindow();
GMap.MoveCamera(CameraUpdateFactory.NewLatLngZoom(
new LatLng(15.354942, 73.929845), 20));
}
}
Adapter
public class MapAdapter : Java.Lang.Object, GoogleMap.IInfoWindowAdapter
{
private IOnTouchListener infoButtonListener;
LayoutInflater inflater;
private Activity context;
public MapAdapter(Activity context)
{
this.context = context;
}
public View GetInfoContents(Marker marker)
{
return null;
}
public View GetInfoWindow(Marker marker)
{
View view = context.LayoutInflater.Inflate(Resource.Layout.CustomWindow, null);
TextView Link1 = (TextView)view.FindViewById(Resource.Id.Link1);
TextView Link2 = (TextView)view.FindViewById(Resource.Id.Link2);
String udata = "Link1";
SpannableString content = new SpannableString(udata);
content.SetSpan(new UnderlineSpan(), 0, udata.Length, 0);
gotoLink.SetText(content,TextView.BufferType.Normal);
String udataPickup = "Link2";
SpannableString contentPickup = new SpannableString(udataPickup);
contentPickup.SetSpan(new UnderlineSpan(), 0, udataPickup.Length, 0);
pickupLink.SetText(contentPickup, TextView.BufferType.Normal);
return view;
}
}
Actually, it is not possible, Google Map renders the content of your custom InfoWindow into an image and displays it to you as an Image. Therefore you set a click Listener only to the whole window and not to the Views inside it.
Your only choice is to set the ClickListener to the whole InfoWindow and popup a Dialog with clickable content you want, and not do it directly inside the InfoWindow.
From Google Docs: https://developers.google.com/maps/documentation/android/marker#info_windows
Note: The info window that is drawn is not a live view. The view is rendered as an image (using View.draw(Canvas)) at the time it is returned. This means that any subsequent changes to the view will not be reflected by the info window on the map. To update the info window later (e.g., after an image has loaded), call showInfoWindow(). Furthermore, the info window will not respect any of the interactivity typical for a normal view such as touch or gesture events. However, you can listen to a generic click event on the whole info window as described in the section below.`
Related
I'm using MapQuest Android SDK in my application.
I have scenario where I drop a pin on map and I want to automatically open a the window for the pin.
I'm using MapboxMap.InfoWindowAdapter and method getInfoWindow( Marker marker) . My question here how to automatically open window as soon as i drop the pin.
I want to open window automatically after dropping the pin?
Here is my code:
#Override
public void onResume() {
super.onResume();
//This is where I pass my poi from poiSearchListview Fragment to my Map Fragment through Activity. So On onResume() if will call this method.
if (null != getActivity.getPoiFields()) {
fromSearchFrag = true;
addPoiMarker(getActivity.getPoiFields());
}
}
This is my OnCreateView() method:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.map, container, false);
mMapView.getMapAsync(new OnMapReadyCallback() {
mPoiFields.clear();
if (null != getActivity.getPoiFields()) {
fromSearch = true;
addPoiMarker(getActivity.getPoiFields());
}
mMapboxMap.setInfoWindowAdapter(new MapboxMap.InfoWindowAdapter() {
#Nullable
#Override
public View getInfoWindow(#NonNull Marker marker) {
View customView = null;
**//Here I have my own window my own images, texts and buttons.**
return custom view;
}
});
}
});
This is my method for adding POIMarker on Map at OnResume()
public void addPoiMarker(Fields poiFields) {
final String name = poiFields.getName();
poiAddress = poiFields.getAddress() + ", " + poiFields.getCity() + ", " + poiFields.getState();
Drawable iconDrawable = ContextCompat.getDrawable(getActivity(), R.drawable.pointofinterest);
Icon icon = IconFactory.getInstance(getActivity()).fromDrawable(iconDrawable);
if (mMapboxMap != null) {
mMapboxMap.removeAnnotations(); // TO remove all the markers before dropping the Address marker from search.
markerOptions = new MarkerOptions().icon(icon).position(
new LatLng(poiFields.getLat(), poiFields.getLng())).title(name);
mSearchResultMarker = mMapboxMap.addMarker(markerOptions);
mPoiFields.put(mSearchResultMarker, poiFields);
// mMapboxMap.selectMarker(mSearchResultMarker);
// **IF I use selectMarker it shows just the address on the window and
not my custom window.
I want to show my custom info window here as selectMarker doesn't clear my issue, what to do ?**.
}
zoomToPin(poiFields.getLat(), poiFields.getLng());
}
Try using mapboxMap.selectMarker() passing in the marker you want to select.
EDIT: I modified the demo app example CustomInfoWindowActivity to produce both scenarios you have mentioned in your comment below. I simulate scenario 1 by simply clicking the map (not animating the marker dropping), this calls mapboxMap.selectMarker() and displays the custom info window as expected. Scenario 2 is working as expected too when clicking the marker icon.
if I'm still not understanding the issue, please provide additional code and pictures/videos/gifs of the issue.
Have you tried invoking the showInfoWindow() method on the Marker?
I want to show the info window on the top right corner of the map when user click on the any marker in google map.
Its info window should always show on the top right corner of the map.
// Setting a custom info window adapter for the google map
mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
// Use default InfoWindow frame if return null
// else inflate any layout
#Override
public View getInfoWindow(Marker marker) {
/*showAlertToChooseImage();*/
if (!marker.getTitle().equalsIgnoreCase("Helipad")) {
// Getting view from the layout file info_window_layout
View view = getActivity().getLayoutInflater().inflate(R.layout.windowlayout, null);
// Getting reference to the TextView to set latitude
TextView tvGroupName = (TextView) view.findViewById(R.id.txtViewGroupName);
tvGroupName.setText(modelItemMarker.getIncidentGropName());
// Getting reference to the TextView to set longitude
TextView tvAddress = (TextView) view.findViewById(R.id.txtViewAddress);
tvAddress.setText(modelItemMarker.getLOCATION_ADDRESS());
TextView tvDateTime = (TextView) view.findViewById(R.id.txtViewDateTime);
tvDateTime.setText(modelItemMarker.getIncidentDateTimeField());
// Returning the view containing InfoWindow contents
return view;
} else {
return null;
}
}
// Defines the contents of the InfoWindow
#Override
public View getInfoContents(Marker arg0) {
return null;
}
});
// Handle click of the infoWindow.
mMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
#Override
public void onInfoWindowClick(Marker marker) {
Bundle bundle = new Bundle();
bundle.putString(Constants.CallNO, modelItemMarker.getCadIdField());
SideMenuFragment_Left.IsChangePwd = false;
SideMenuFragment_Right.IsAgencies = false;
Intent intent = new Intent(mContext, IncidentDetailActivity.class);
intent.putExtra(Constants.INCIDENT_DETAIL, bundle);
startActivity(intent);
}
});
Can anybody please help.
Thanks in advance
try on this way .
public class MarkerDemoActivity extends AppCompatActivity implements
OnInfoWindowClickListener,
OnMapReadyCallback {
private GoogleMap mMap;
#Override
public void onMapReady(GoogleMap map) {
mMap = map;
// Add markers to the map and do other map setup.
...
// Set a listener for info window events.
mMap.setOnInfoWindowClickListener(this);
}
#Override
public void onInfoWindowClick(Marker marker) {
Toast.makeText(this, "Info window clicked",
Toast.LENGTH_SHORT).show();
}
}
As the above code you will get the info window top of the marker.But if you want to do top left corner i am thinking you need to take one more layout and you have to add this layout to maps activity on clicking of marker.
Current functions from Google Maps API for Android cannot achieve that. Try implementing it to your Android App using the Google Maps Javascript API via a WebFrame instead.
You can use the InfoWindowOptions to customize the position by using the pixelOffset positions option
More info on that here.
I have a custom "InfoWindow" for a marker, which has buttons, but for default user can't click over the buttons or slide on lists of that layout because that info window is like an image.
Note: the solution in https://stackoverflow.com/a/15040761/2183804 doesn't apply to my problem because different markers has different info Windows (I already tried modifying that answer without success).
So, to solve my problem, I though on putting a layout above the marker when the user clicks over the marker. How can I achieve to put the layout above the marker?
In this example, I have a list with clickable items in the layout
A solution can be find on this link: https://stackoverflow.com/a/31995000/3957303
The basic idea is to use a PopupWindow to show the layout on the screen, and then play with its location to potition it over the marker with the updatePopup method described in the answer. And every time the camera changes (listening to the CameraChangeListener), you call the updatePopup method.
I have achieved this by adding a custom info window adapter. And then set it to my map . And in getInfoWindow() of adapter ,you can write all the click listeners to your views.Here is the code .
private class CustomInfoWindowAdapter implements GoogleMap.InfoWindowAdapter {
private View view;
public CustomInfoWindowAdapter() {
view = getLayoutInflater().inflate(R.layout.custom_info_window, null);
}
#Override
public View getInfoContents(Marker marker) {
if (marker != null
&& marker.isInfoWindowShown()) {
marker.hideInfoWindow();
marker.showInfoWindow();
}
return null;
}
#Override
public View getInfoWindow(final Marker marker) {
final ImageView image = ((ImageView) view.findViewById(R.id.badge));
final String title = marker.getTitle();
final TextView titleUi = ((TextView) view.findViewById(R.id.title));
if (title != null) {
titleUi.setText(title);
} else {
titleUi.setText("");
}
return view;
}
}
And set it to map by this
private GoogleMap mMap;
mMap.setInfoWindowAdapter(new CustomInfoWindowAdapter());
Hope it helps. Happy coding...
I'm trying to create an android widget based on a ViewSwitcher with a MapView and StreetViewPanoramaView inside. Users can switch from street to map view with a overlayed control bar.
So far all is working fine for the map part, but not for the street view part.
On first display it seems to work but when i tried to move inside (pan and/or zoom) StreetViewPanorama crash (become black).
this is how i create my StreetViewPanorama :
final StreetViewPanoramaOptions options = new StreetViewPanoramaOptions();
options.streetNamesEnabled(true)
.zoomGesturesEnabled(true)
.panningGesturesEnabled(true);
mStreetView = new StreetViewPanoramaView(getActivity(), options);
mStreetView.onCreate(savedInstanceState);
And how I defiened the location for both (map and street view)
// Set map to position and add a new marker
final GoogleMap map = mMapView.getMap();
map.moveCamera(CameraUpdateFactory.newLatLngZoom(mLocation, DEFAULT_ZOOM_LEVEL));
if (mMarker != null){
mMarker.remove();
}
mMarker = map.addMarker(new MarkerOptions().draggable(false).position(mLocation));
// Set street view to location.
final StreetViewPanorama street = mStreetView.getStreetViewPanorama();
street.setPosition(mLocation, 50);
// Hide by default controls and street view button.
// I will be enabled only if it's a valid street view location
mControlsView.setVisibility(View.GONE);
mStreetBtnContainer.setVisibility(View.GONE);
switchToMapView();
// we must add a delay to check if the new street view location is valid.
// see : http://stackoverflow.com/a/23785186
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
mHasStreetView = street.getLocation() != null;
if (mHasStreetView){
mStreetBtnContainer.setVisibility(View.VISIBLE);
}
showControlView();
}
}, STREET_DELAY_MILLIS);
Did someone encounter the same problem ?
Cheers.
In my android app, I have a info window for a marker I place on the map. I want to do these things:
Make the default marker bigger (its too small now)
When the info window shows up, the text in it is making the width too long. Is there a way I can set a maximum width on it?
How can I increase the font size for the title and text?
Can anyone show me how to do this?
Thanks.
Maybe a little late, but you need to create a new custom adapter you can take a look in here: How to change Google Maps marker window Info
mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
#Override
public View getInfoWindow(com.google.android.gms.maps.model.Marker arg0) {
return null;
}
#Override
public View getInfoContents(com.google.android.gms.maps.model.Marker marker) {
LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
View mView = null;
//using the id, you can store multiple types of markers on List's and change the layout
if (marker.getId().equals(end.getId())) {
mView = inflater.inflate(R.layout.custom_info_window, (ViewGroup) findViewById(R.id.map), false);
((TextView) mView.findViewById(R.id.txtTitle)).setText(marker.getTitle());
}else{
mView = inflater.inflate(R.layout.normal_info_window, (ViewGroup) findViewById(R.id.map), false);
((TextView) mView.findViewById(R.id.txtTitle)).setText(marker.getTitle());
((TextView) mView.findViewById(R.id.txtDescription)).setText(marker.getSnippet());
}
return mView;
}
});
mMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
#Override
public void onInfoWindowClick(Marker marker) {
//do whatever you need
}
});
In te custom view you can modify the size of the font, and other things, for the first point the marker icon can be modified on the MarkerOptions.setIcon, where you can use one from your assets.
1: When you add the Marker to the map, you can set the icon in the MarkerOptions. Make your own icon and use that.
2 & 3: Set an onMarkerClickListener on your GoogleMap. In the callback, you can create and show your own info window view on the map (just make sure you return false from the onMarkerClick() callback)