android google-maps google-maps-markers infowindow

Android Maps Utils Clustering show InfoWindow



google-maps google-maps-markers (3)

Aquí hay una solución simplificada y ligeramente modificada basada en esta respuesta . Tenga en cuenta que la respuesta vinculada implementa una ventana de información tanto para marcadores como para clústeres.

Esta solución solo implementa InfoWindows para marcadores.

Es similar a cómo implementaría un InfoWindowAdapter personalizado para marcadores normales sin agrupamiento, pero con el requisito adicional de que mantenga una referencia al elemento seleccionado actualmente para que pueda obtener el título y el MyItem instancia MyItem , ya que el marcador sí no almacene el Título y el Fragmento como generalmente lo hace.

Tenga en cuenta que, dado que todos los datos se almacenan en referencias de MyItem , es mucho más fácil ampliar la funcionalidad para mostrar tantos tipos de datos como desee en la ventana de información para cada marcador.

Primero, MyItem.java, que incluye campos adicionales para Título y Fragmento:

public class MyItem implements ClusterItem { private final LatLng mPosition; private final String mTitle; private final String mSnippet; public MyItem(double lat, double lng, String t, String s) { mPosition = new LatLng(lat, lng); mTitle = t; mSnippet = s; } @Override public LatLng getPosition() { return mPosition; } public String getTitle(){ return mTitle; } public String getSnippet(){ return mSnippet; } }

Aquí está la clase de actividad completa, que incluye toda la funcionalidad para admitir InfoWindows para cada marcador agregado mediante la biblioteca de clúster:

Editar: Se agregó soporte para manejar eventos de clic en InfoWindow, hizo que la actividad implementara OnClusterItemInfoWindowClickListener y agregó la onClusterItemInfoWindowClick llamada onClusterItemInfoWindowClick .

public class MapsActivity extends AppCompatActivity implements ClusterManager.OnClusterItemInfoWindowClickListener<MyItem> { private ClusterManager<MyItem> mClusterManager; private MyItem clickedClusterItem; private GoogleMap mMap; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_maps); setUpMapIfNeeded(); } @Override protected void onResume() { super.onResume(); setUpMapIfNeeded(); } private void setUpMapIfNeeded() { // Do a null check to confirm that we have not already instantiated the map. if (mMap == null) { // Try to obtain the map from the SupportMapFragment. mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)) .getMap(); // Check if we were successful in obtaining the map. if (mMap != null) { setUpMap(); } } } private void setUpMap() { mMap.getUiSettings().setMapToolbarEnabled(true); mMap.getUiSettings().setZoomControlsEnabled(true); mMap.setMyLocationEnabled(true); mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); mClusterManager = new ClusterManager<>(this, mMap); mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(37.779977,-122.413742), 10)); mMap.setOnCameraChangeListener(mClusterManager); mMap.setOnMarkerClickListener(mClusterManager); mMap.setInfoWindowAdapter(mClusterManager.getMarkerManager()); mMap.setOnInfoWindowClickListener(mClusterManager); //added mClusterManager.setOnClusterItemInfoWindowClickListener(this); //added mClusterManager .setOnClusterItemClickListener(new ClusterManager.OnClusterItemClickListener<MyItem>() { @Override public boolean onClusterItemClick(MyItem item) { clickedClusterItem = item; return false; } }); addItems(); mClusterManager.getMarkerCollection().setOnInfoWindowAdapter( new MyCustomAdapterForItems()); } private void addItems() { double latitude = 37.779977; double longitude = -122.413742; for (int i = 0; i < 10; i++) { double offset = i / 60d; double lat = latitude + offset; double lng = longitude + offset; MyItem offsetItem = new MyItem(lat, lng, "title " + i+1, "snippet " + i+1); mClusterManager.addItem(offsetItem); } } //added with edit @Override public void onClusterItemInfoWindowClick(MyItem myItem) { //Cluster item InfoWindow clicked, set title as action Intent i = new Intent(this, OtherActivity.class); i.setAction(myItem.getTitle()); startActivity(i); //You may want to do different things for each InfoWindow: if (myItem.getTitle().equals("some title")){ //do something specific to this InfoWindow.... } } public class MyCustomAdapterForItems implements GoogleMap.InfoWindowAdapter { private final View myContentsView; MyCustomAdapterForItems() { myContentsView = getLayoutInflater().inflate( R.layout.info_window, null); } @Override public View getInfoWindow(Marker marker) { TextView tvTitle = ((TextView) myContentsView .findViewById(R.id.txtTitle)); TextView tvSnippet = ((TextView) myContentsView .findViewById(R.id.txtSnippet)); tvTitle.setText(clickedClusterItem.getTitle()); tvSnippet.setText(clickedClusterItem.getSnippet()); return myContentsView; } @Override public View getInfoContents(Marker marker) { return null; } } }

info_window.xml:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="20dp" android:orientation="vertical" android:background="#000000"> <TextView android:id="@+id/txtTitle" android:textColor="#D3649F" android:textStyle="bold" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/txtSnippet" android:textColor="#D3649F" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>

Resultado:

Lanzamiento inicial:

Al alejarse, comienza la agrupación:

Alejando de nuevo, más agrupamiento:

Luego, acercar y hacer clic en un marcador individual:

Luego haciendo clic en otro marcador:

Editar: para mostrar el "globo de diálogo" alrededor de la ventana de información personalizada, use getInfoContents() lugar de getInfoWindow() :

public class MyCustomAdapterForItems implements GoogleMap.InfoWindowAdapter { private final View myContentsView; MyCustomAdapterForItems() { myContentsView = getLayoutInflater().inflate( R.layout.info_window, null); } @Override public View getInfoWindow(Marker marker) { return null; } @Override public View getInfoContents(Marker marker) { TextView tvTitle = ((TextView) myContentsView .findViewById(R.id.txtTitle)); TextView tvSnippet = ((TextView) myContentsView .findViewById(R.id.txtSnippet)); tvTitle.setText(clickedClusterItem.getTitle()); tvSnippet.setText(clickedClusterItem.getSnippet()); return myContentsView; } }

Resultado:

Estoy planeando usar el grupo de marcadores de Google Maps disponible en la biblioteca de utilidades, pero la aplicación de ejemplo de Google solo muestra grupos de marcadores sin ninguna ventana de información. Me pregunto ahora, ¿no puedo mostrar una ventana de información? Quiero que la ventana de información se muestre en el marcador como con un marcador de Google Maps normal, no en el clúster.

El código que tengo: (Del ejemplo de google)

public class BigClusteringDemoActivity extends FragmentActivity { private ClusterManager<MyItem> mClusterManager; private GoogleMap mMap; private void readItems() { InputStream inputStream = getResources().openRawResource(R.raw.radar_search); List<MyItem> items = new MyItemReader().read(inputStream); for (int i = 0; i < 10; i++) { double offset = i / 60d; for (MyItem item : items) { LatLng position = item.getPosition(); double lat = position.latitude + offset; double lng = position.longitude + offset; MyItem offsetItem = new MyItem(lat, lng); mClusterManager.addItem(offsetItem); } } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.map); mClusterManager = new ClusterManager<>(this, mMap); mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap(); mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(51.503186, -0.126446), 10)); mMap.setOnCameraChangeListener(mClusterManager); readItems(); } }


Podría considerar el siguiente enfoque:

public void initilizeMap() { googleMap = mFragment.getMap(); googleMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN); googleMap.getUiSettings().setZoomControlsEnabled(true`enter code here`); // true to`enter code here` googleMap.getUiSettings().setZoomGesturesEnabled(true); googleMap.getUiSettings().setCompassEnabled(true); googleMap.getUiSettings().setMyLocationButtonEnabled(true); googleMap.getUiSettings().setRotateGesturesEnabled(true); if (googleMap == null) { Toast.makeText(getActivity(), "Sorry! unable to create maps", Toast.LENGTH_SHORT).show(); } mClusterManager = new ClusterManager<MyItem>(getActivity(), googleMap ); // googleMap.setInfoWindowAdapter(new CustomInfoWindowAdapter()); googleMap.setOnMapLoadedCallback(this); googleMap.setMyLocationEnabled(true); googleMap.setBuildingsEnabled(true); googleMap.getUiSettings().setTiltGesturesEnabled(true); MyItem offsetItem = new MyItem(Double.parseDouble(outletList.get(i).getMap_latitude()), Double.parseDouble(outletList.get(i).getMap_longitude()), title , address); mClusterManager.addItem(offsetItem); googleMap.setInfoWindowAdapter(new CustomInfoWindowAdapter(offsetItem)); } private class CustomInfoWindowAdapter implements InfoWindowAdapter { Marker marker; private View view; private MyItem items; public CustomInfoWindowAdapter(MyItem item) { view = getActivity().getLayoutInflater().inflate( R.layout.custom_info_window, null); this.items = item; } @Override public View getInfoContents(Marker marker) { if (marker != null && marker.isInfoWindowShown()) { marker.hideInfoWindow(); marker.showInfoWindow(); } return null; } @Override public View getInfoWindow(final Marker marker) { this.marker = marker; String url = null; if (marker.getId() != null && markers != null && markers.size() > 0) { if (markers.get(marker.getId()) != null && markers.get(marker.getId()) != null) { url = markers.get(marker.getId()); } } final ImageView image = ((ImageView) view.findViewById(R.id.badge)); if (url != null && !url.equalsIgnoreCase("null") && !url.equalsIgnoreCase("")) { imageLoader.displayImage(url, image, options, new SimpleImageLoadingListener() { @Override public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { super.onLoadingComplete(imageUri, view, loadedImage); getInfoContents(marker); } }); } else { image.setImageResource(R.drawable.ic_launcher); } final String title = items.getTitle(); Log.e(TAG, "TITLE : "+title); final TextView titleUi = ((TextView) view.findViewById(R.id.title)); if (title != null) { titleUi.setText(title); } else { titleUi.setText(""); } final String address = items.getAddress(); final TextView snippetUi = ((TextView) view .findViewById(R.id.snippet)); if (address != null) { snippetUi.setText(address); } else { snippetUi.setText(""); }


@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.map); mClusterManager = new ClusterManager<>(this, mMap); mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap(); mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(51.503186, -0.126446), 10)); mMap.setOnCameraChangeListener(mClusterManager); mMap.setInfoWindowAdapter(new InfoWindowAdapter() { /** * View for displaying marker popup, if null default framework view would be used */ @Override public View getInfoWindow(Marker marker) { return null; } /** * For changing the content of infowindow * Called when showMarkerInfo method is called */ @Override public View getInfoContents(Marker marker) { View v = getLayoutInflater().inflate(R.layout.view_to_inflate, null); //code for initializing view part return v; } }); readItems(); }