How to display marker infowindow when map loads? when im clicking the map name a new activity starts where the map loads.It shows the marker,the problem is i want to automatically display also the custom infowindow i created.Here's my code below: I will mark this answer for those who can fix this. thanks.
if (nameList.get(i).equals(selected)){
Marker marker = map.addMarker(new MarkerOptions()
.title(nameList.get(i))
.snippet(addressList.get(i))
.icon(BitmapDescriptorFactory.fromResource(R.drawable.marker_location))
.position(new LatLng(latList.get(i), lngList.get(i))));
marker.showInfoWindow();
//Set Custom InfoWindow
map.setInfoWindowAdapter(new InfoWindowAdapter() {
#Override
public View getInfoWindow(Marker arg0) {
return null;
}
#Override
public View getInfoContents(Marker marker) {
View myContentsView = getLayoutInflater().inflate(R.layout.map_info, null);
TextView tvTitle = ((TextView)myContentsView.findViewById(R.id.title));
tvTitle.setText(marker.getTitle());
TextView tvSnippet = ((TextView)myContentsView.findViewById(R.id.snippet));
tvSnippet.setText(marker.getSnippet());
TextView infoSnippet = (TextView)myContentsView.findViewById(R.id.moreinfo);
infoSnippet.setText("Click for more details.");
return myContentsView;
}
});
//Open New Activity
map.setOnInfoWindowClickListener(new OnInfoWindowClickListener() {
#Override
public void onInfoWindowClick(Marker marker) {
Intent intent = new Intent(SelectedPlaceActivity.this, PlaceDescriptionActivity.class);
intent.putExtra("placetitle", marker.getTitle().toString());
intent.putExtra("snippet", marker.getSnippet().toString());
startActivity(intent);
}
});
}
It seems that you need an InfoWindow adapter. See the following example:
map.setInfoWindowAdapter(new InfoWindowAdapter(){
// Use default InfoWindow frame
#Override
public View getInfoWindow(Marker marker) {
return null;
}
// Defines the contents of the InfoWindow
#Override
public View getInfoContents(Marker marker) {
// Getting view from the layout file info_window_layout
View v = getLayoutInflater().inflate(R.layout.custom_info_window, null);
// Getting reference to the TextView to set title
TextView note = (TextView) v.findViewById(R.id.note);
note.setText(marker.getTitle() );
return v;
}
});
As you can see, you need to create a custom layout. In my example:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView android:id="#+id/note"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textColor="#000000"/>
<ImageButton android:id="#+id/takeMeThere"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/note"
android:contentDescription="#string/directions"
android:src="#drawable/ic_action_directions"
android:background="#null"/>
</RelativeLayout>
Hope this helps
According to the documents of Google Maps for Android V2:
An info window allows you to display information to the user when they
tap on a marker on a map. By default, an info window is displayed when
a user taps on a marker if the marker has a title set. Only one info
window is displayed at a time. If a user clicks on another marker, the
current window will be hidden and the new info window will be
displayed. You can show an info window programmatically by calling
showInfoWindow() on the target marker. An info window can be hidden by
calling hideInfoWindow().
Related
I use a customized info window so that I can achieve a gray background and white text color. Yet, I get a white frame around it. I want all of the Info Window to be gray, that is including its triangular edge that points to the spot.
I use this code in my Activity:
map.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
#Override // Use default InfoWindow frame
public View getInfoWindow(Marker marker) { return null; }
#Override // Defines the contents of the InfoWindow
public View getInfoContents(Marker marker) {
View v = getLayoutInflater().inflate(R.layout.map_info_window, null);
TextView tv_location = (TextView) v.findViewById(R.id.tv_location);
tv_location.setText(marker.getTitle());
return v;
}});
and this is my layout:
<!--?xml version="1.0" encoding="utf-8"?-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/map_info_window"
android:layout_width="match_parent"
android:background="#color/light_grey"
android:orientation="horizontal"
android:layout_height="match_parent" >
<TextView
android:id="#+id/tv_location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/white" />
</LinearLayout>
You have to override the getInfoWindow () method and inflate you custom layout in that function.
From Documentation
public abstract View getInfoWindow (Marker marker)
Provides a custom info window for a marker. If this method returns a
view, it is used for the entire info window. If you change this view
after this method is called, those changes will not necessarily be
reflected in the rendered info window. If this method returns null ,
the default info window frame will be used, with contents provided by
getInfoContents(Marker).
#Override // Use default InfoWindow frame
public View getInfoWindow (Marker marker){
View v = getLayoutInflater().inflate(R.layout.map_info_window, null);
TextView tv_location = (TextView) v.findViewById(R.id.tv_location);
tv_location.setText(marker.getTitle());
return v;
}
#Override // Defines the contents of the InfoWindow
public View getInfoContents (Marker marker){
// TODO Auto-generated method stub
return null;
}
So i think you should reverse your function implementation.
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 need custom info window with two clickable button as above.In it when more then marker and click any one of them then window should be open and when click on another marker another window should open and close previous window as well in single click.
is there any specific reason why google map v2 not support live component like button ,check box?
What you are trying to achieve is possible.
You can see the recipe in this answer: https://stackoverflow.com/a/15040761/2183804
And a working implementation on Google Play.
MainActivity.java
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class MainActivity extends Activity {
private ViewGroup infoWindow;
private TextView infoTitle;
private TextView infoSnippet;
private Button infoButton1, infoButton2;
private OnInfoWindowElemTouchListener infoButtonListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mapwrapperlauot);
final MapFragment mapFragment =
(MapFragment) getFragmentManager().findFragmentById(R.id.map);
final MapWrapperLayout mapWrapperLayout =
(MapWrapperLayout) findViewById(R.id.map_relative_layout);
final GoogleMap map = mapFragment.getMap();
mapWrapperLayout.init(map, getPixelsFromDp(this, 39 + 20));
final Marker ki = map.addMarker(new MarkerOptions()
.position(new LatLng(50.08, 14.43))
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.circles)));
infoWindow = (ViewGroup) getLayoutInflater()
.inflate(R.layout.activity_main, null);
infoButton1 = (Button) infoWindow.findViewById(R.id.b1);
infoButton2 = (Button) infoWindow.findViewById(R.id.b2);
infoButtonListener = new OnInfoWindowElemTouchListener(infoButton1,
getResources().getDrawable(R.drawable.ic_launcher),
getResources().getDrawable(R.drawable.ic_launcher)) {
#Override
protected void onClickConfirmed(View v, Marker marker) {
Toast.makeText(getApplicationContext(),
"click on button 1", Toast.LENGTH_LONG).show();
}
};
infoButton1.setOnTouchListener(infoButtonListener);
infoButtonListener = new OnInfoWindowElemTouchListener(infoButton2,
getResources().getDrawable(R.drawable.ic_launcher),
getResources().getDrawable(R.drawable.ic_launcher)) {
#Override
protected void onClickConfirmed(View v, Marker marker) {
Toast.makeText(getApplicationContext(),
"click on button 2", Toast.LENGTH_LONG).show();
}
};
infoButton2.setOnTouchListener(infoButtonListener);
infoWindow.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
map.setInfoWindowAdapter(new InfoWindowAdapter() {
#Override
public View getInfoWindow(Marker marker) {
infoButtonListener.setMarker(marker);
mapWrapperLayout.setMarkerWithInfoWindow(marker, infoWindow);
return infoWindow;
}
#Override
public View getInfoContents(Marker marker) {
// Setting up the infoWindow with current's marker info
return null;
}
});
ki.showInfoWindow();
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(50.08, 14.43), 15));
map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
}
public static int getPixelsFromDp(Context context, float dp) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dp * scale + 0.5f);
}
}
activity_main
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:background="#drawable/marker" >
<Button
android:id="#+id/b1"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Button1"
android:layout_marginBottom="10dp" />
<Button
android:id="#+id/b2"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Button2"
android:layout_marginBottom="10dp" />
</LinearLayout>
</RelativeLayout>
now copy the following files from the link https://stackoverflow.com/a/15040761/2183804
mapwrapperlauot (include your package name in tag)
MapWrapperLayout.java
OnInfoWindowElemTouchListener.java
It will work.
I have build a sample android studio project for this question.
output screen shots :-
Download full project source code Click here
Please note: you have to add your API key in Androidmanifest.xml
What you are trying to achieve is not possible. Even if you create an XML layout for your info-window, info window contents are rendered and presented as an image on the maps. So it can accept only one click listener for the whole window. You can't specify multiple click listeners for a window.
UPDATE:
From the Docs:
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.
There is actually a library that can resolve your problem and add an info window that is a live view and you can interact with it.
https://github.com/Appolica/InteractiveInfoWindowAndroid
I have made lot of markers now I want each information window of marker must be unique I have written xml for information window but its not working accordingly every time a single image shows up.
// Setting a custom info window adapter for the google map
myMap.setInfoWindowAdapter(new InfoWindowAdapter() {
// Use default InfoWindow frame
public View getInfoWindow(Marker arg0) {
return null;
}
// Defines the contents of the InfoWindow
public View getInfoContents(Marker marker) {
// Getting view from the layout file info_window_layout
View v = getLayoutInflater().inflate(
R.layout.info_window_layout, null);
// Getting the position from the marker
LatLng latLng = marker.getPosition();
Double latitude=latLng.latitude;
Double langitude=latLng.longitude;
String lat = String.format("%.6f", latitude);
String lng = String.format("%.6f", langitude);
Toast.makeText(getApplicationContext(), lat+"----"+lng,Toast.LENGTH_SHORT).show();
// Getting reference to the TextView to set longitude
TextView tvLng = (TextView) v.findViewById(R.id.tv1);
ImageView icon = (ImageView) v.findViewById(R.id.icons);
if(lat.equals("73.057130") && lng.equals("33.721140"))
{
icon.setImageResource(R.drawable.hbl_icon);
}
else
{
icon.setImageResource(R.drawable.alflah_icon);
}
// Returning the view containing InfoWindow contents
return v;
}
});
in myMap.setInfoWindowAdapter the toast is showing the same latitude but the information window appearing is not showing the image in if condition and always showing a image in else condition.everything works fine but the image is not showing proper kindly help.
my xml is :
<?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" >
<ImageView
android:id="#+id/icons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp" />
<TextView
android:id="#+id/tv1"
android:text="Get Directions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp" />
</LinearLayout>
You should not use LatLng to identify Marker because of this bug.
You may use title / snippet instead and make ifs on that value or have a Map<Marker, YourModel> of all markers and keep icon resource id in that model.
Or you can use Android Maps Extensions, which adds functions like Marker.setData(Object) and Object Marker.getData() and keep your model with icon resource id close to marker.
for(int i = 0 ; i < arraylist.size();i++){
addMarker(mapview,arraylistLat.get(i),arraylistLong.get(i),title.get(i),arraysnippet.get(i),imageid[i]);
}
private void addMarker(GoogleMap map, double lat, double lon,
String string, String string2,int imgid) {
map.addMarker(new MarkerOptions().position(new LatLng(lat, lon))
.title(string).snippet(string2).icon(BitmapDescriptorFactory.fromResource(imgid));
}
Here imgid is the id of drawable resource.
I have a custom layout for my map's window info, but I can't see any example of how to pass the data from the marker.
Anybody can help?
mMap.setInfoWindowAdapter(new InfoWindowAdapter() {
// Use default InfoWindow frame
#Override
public View getInfoWindow(Marker arg0) {
return null;
}
#Override
public View getInfoContents(Marker arg0) {
View v = getActivity().getLayoutInflater().inflate(R.layout.info_window_layout, null);
ImageView pic = (ImageView) v.findViewById(R.id.pic);
String url = <????>;
// set pic image from url
TextView name = (TextView) v.findViewById(R.id.name);
name.setText(<????>);
TextView address = (TextView) v.findViewById(R.id.address);
address.setText(<????>);
return v;
}
});
mCenterList = MyApplication.dbHelper.getAllCenter();
for(Center center : mCenterList){
Marker marker = mMap.addMarker(
new MarkerOptions().position(new LatLng(center.lat, center.lng))
.icon(BitmapDescriptorFactory.fromResource(R.drawable.elipin)));
// How can I pass custom data, here pic, name and address, to the marker, to
// make it available in getInfoContents?
}
info_window_layout.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="300dp"
android:layout_height="50dp"
android:padding="5dp" >
<ImageView
android:id="#+id/pic"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginRight="5dp"
android:scaleType="centerCrop" />
<ImageView
android:id="#+id/arrow"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:layout_marginLeft="5dp"
android:scaleType="centerCrop"
android:src="#drawable/arrowri" />
<TextView
android:id="#+id/name"
android:layout_width="match_parent"
android:layout_height="25dp"
android:layout_toRightOf="#id/pic"
android:layout_toLeftOf="#id/arrow"
android:gravity="center_vertical"
android:singleLine="true"
android:textColor="#ffffff"
android:textSize="18sp" />
<TextView
android:id="#+id/address"
android:layout_width="match_parent"
android:layout_height="15dp"
android:layout_toRightOf="#id/pic"
android:layout_toLeftOf="#id/arrow"
android:layout_below="#id/name"
android:gravity="center_vertical"
android:singleLine="true"
android:textColor="#ffffff"
android:textSize="16sp" />
</RelativeLayout>
Since Marker is final, you cannot create a subclass from it.
Hence, the best solution that I have found is to use something in the Marker -- such as the snippet -- to hold a key that allows you to look up additional data. For example, it might be the key to a HashMap of your data model, or it might be the primary key for your database, or something.
Then, your <????> do not come from the Marker directly, but from your real data model, where the Marker just has the identifying information to tie the two together.
I found this library Android Maps Extentions and I used it in my project. It's useful and it can help you easy to pass data into window.
Thanks,
I solved this by storing my data inside an array, creating a custom layout for the infowindow, and after that passing the indexer of the array after the title so: "title/indexer". Inside the infowindow I split the string and the used the indexer to use the array, and get the data.
Take a look at this code example, there are comments in the code for explanation:
map.setInfoWindowAdapter(new InfoWindowAdapter() {
// Use default InfoWindow frame
#Override
public View getInfoWindow(Marker args) {
return null;
}
// Defines the contents of the InfoWindow
#Override
public View getInfoContents(Marker args) {
// Getting view from the layout file info_window_layout
View v = getLayoutInflater().inflate(R.layout.info_window_layout, null);
// Getting the position from the marker
clickMarkerLatLng = args.getPosition();
//Setting title text
TextView title = (TextView) v.findViewById(R.id.tvTitle);
title.setText(args.getTitle());
map.setOnInfoWindowClickListener(new OnInfoWindowClickListener() {
public void onInfoWindowClick(Marker marker)
{
if (SGTasksListAppObj.getInstance().currentUserLocation!=null)
{
if (String.valueOf(SGTasksListAppObj.getInstance().currentUserLocation.getLatitude()).substring(0, 8).contains(String.valueOf(clickMarkerLatLng.latitude).substring(0, 8)) &&
String.valueOf(SGTasksListAppObj.getInstance().currentUserLocation.getLongitude()).substring(0, 8).contains(String.valueOf(clickMarkerLatLng.longitude).substring(0, 8)))
{
Toast.makeText(getApplicationContext(), "This your current location, navigation is not needed.", Toast.LENGTH_SHORT).show();
}
else
{
FlurryAgent.onEvent("Start navigation window was clicked from daily map");
tasksRepository = SGTasksListAppObj.getInstance().tasksRepository.getTasksRepository();
for (Task tmptask : tasksRepository)
{
String tempTaskLat = String.valueOf(tmptask.getLatitude());
String tempTaskLng = String.valueOf(tmptask.getLongtitude());
Log.d(TAG, String.valueOf(tmptask.getLatitude())+","+String.valueOf(clickMarkerLatLng.latitude).substring(0, 8));
if (tempTaskLat.contains(String.valueOf(clickMarkerLatLng.latitude).substring(0, 8)) && tempTaskLng.contains(String.valueOf(clickMarkerLatLng.longitude).substring(0, 8)))
{
task = tmptask;
break;
}
}
Intent intent = new Intent(getApplicationContext() ,RoadDirectionsActivity.class);
intent.putExtra(TasksListActivity.KEY_ID, task.getId());
startActivity(intent);
}
}
else
{
Toast.makeText(getApplicationContext(), "Your current location could not be found,\nNavigation is not possible.", Toast.LENGTH_SHORT).show();
}
}
});
// Returning the view containing InfoWindow contents
return v;
}
});
UPDATE:
Then you should associate a HashMap object to your marker, take a look at this answer here:
How to link Google Maps Android API v2 Marker to an object
The below method
mMap.setOnMarkerClickListener(new OnMarkerClickListener() {
#Override
public boolean onMarkerClick(**Marker arg0**) { }
helps to pass the value .
ie Marker parameter returns the marker count like 1,2 ,3 etc.
Pass this number like arraylist.get(1).details,you can retrieve the corresponding details
from list