Android Maps Utils Clustering显示InfoWindow

时间:2015-06-20 19:50:01

标签: android google-maps google-maps-markers infowindow

我计划使用utils库中提供的谷歌地图标记群集,但谷歌示例应用程序仅显示没有任何infoWindow的标记群集。我现在想知道,我不能展示InfoWindow吗?我希望InfoWindow显示在标记上,就像使用普通的谷歌地图标记一样,而不是在群集上。

我的代码:(来自谷歌示例)

onProgressUpdate()

3 个答案:

答案 0 :(得分:31)

以下是基于this answer的简化且略有修改的解决方案。请注意,链接的答案为标记和群集实现了InfoWindow。

此解决方案仅实现InfoWindows for Markers。

它类似于如何为没有群集的普通标记实现自定义InfoWindowAdapter,但附加要求是保留对当前所选项目的引用,以便您可以从中获取标题和代码段#39; s MyItem实例,因为Marker不会像往常一样存储Title和Snippet。

请注意,由于所有数据都存储在MyItem引用中,因此扩展功能以在InfoWindow中为每个标记显示所需数量的数据类型要容易得多。

首先,MyItem.java包含Title和Snippet的额外字段:

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;
    }
}

这是完整的Activity类,其中包含支持使用Cluster库添加的每个Marker的InfoWindows的所有功能:

编辑:添加了对在InfoWindow上处理点击事件的支持,使活动实施OnClusterItemInfoWindowClickListener并添加了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>

结果:

首次发布:

enter image description here

缩小,开始群集:

enter image description here

再次缩小,更多聚类:

enter image description here

然后,放大并单击单个标记:

enter image description here

然后点击另一个标记:

enter image description here

编辑:为了显示&#34;语音泡沫&#34;在自定义InfoWindow周围,使用getInfoContents()代替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;
    }
}

结果:

enter image description here

答案 1 :(得分:0)

  @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();
    }

答案 2 :(得分:0)

您可以考虑以下方法:

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("");
            }