简体   繁体   English

Android Maps Utils Clustering 显示 InfoWindow

[英]Android Maps Utils Clustering show InfoWindow

I am planning to use the google maps marker clustering available in the utils library, but the google example app only shows marker clusters without any infoWindow.我计划使用 utils 库中可用的 google maps 标记集群,但 google 示例应用程序仅显示没有任何 infoWindow 的标记集群。 I am wondering now, am I not able to show a InfoWindow?我现在想知道,我不能显示 InfoWindow 吗? I want the InfoWindow to be displayed on the marker like with a normal google maps marker, not on the cluster.我希望 InfoWindow 像普通的谷歌地图标记一样显示在标记上,而不是在集群上。

The code I have: (From the google example)我拥有的代码:(来自谷歌示例)

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

}

Here is a simplified and slightly modified solution based on this answer .这是基于此答案的简化和稍微修改的解决方案。 Note that the linked answer implements an InfoWindow for both Markers and Clusters.请注意,链接的答案为标记和集群实现了一个信息窗口。

This solution only implements InfoWindows for Markers.此解决方案仅为标记实现 InfoWindows。

It's similar to how you would implement a custom InfoWindowAdapter for normal Markers with no Clustering, but with the additional requirement that you keep a reference to the currently selected Item so that you can get the Title and Snippet from it's MyItem instance, since the Marker does not store the Title and Snippet as it usually does.它类似于为没有集群的普通标记实现自定义 InfoWindowAdapter 的方式,但有一个额外的要求,即您保留对当前所选项目的引用,以便您可以从它的MyItem实例中获取标题和代码段,因为标记确实不要像往常一样存储标题和代码段。

Note that since all of the data is stored in MyItem references, it's much easier to extend the functionality to display as many data types as you want in the InfoWindow for each Marker.请注意,由于所有数据都存储在MyItem引用中,因此扩展功能以在信息窗口中为每个标记显示任意数量的数据类型要容易得多。

First, the MyItem.java, which includes extra fields for Title and Snippet:首先是 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;
    }
}

Here is the full Activity class, which includes all of the functionality to support InfoWindows for each Marker added using the Cluster library:这是完整的 Activity 类,其中包括为使用 Cluster 库添加的每个标记支持 InfoWindows 的所有功能:

Edit: Added support for handling click events on the InfoWindow, made the Activity implement OnClusterItemInfoWindowClickListener and added the onClusterItemInfoWindowClick callback.编辑:添加了对处理 InfoWindow 上的单击事件的支持,使 Activity 实现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: 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>

Result:结果:

Initial launch:初始启动:

在此处输入图片说明

Zooming out, starts Clustering:缩小,开始聚类:

在此处输入图片说明

Zooming out again, more Clustering:再次缩小,更多聚类:

在此处输入图片说明

Then, zooming in, and clicking on an individual Marker:然后,放大并单击单个标记:

在此处输入图片说明

Then clicking on another Marker:然后点击另一个标记:

在此处输入图片说明

Edit: In order to show the "speech bubble" around the custom InfoWindow, use getInfoContents() instead of getInfoWindow() :编辑:为了在自定义 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;
    }
}

Result:结果:

在此处输入图片说明

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

You could consider the following approach:您可以考虑以下方法:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM