Android Maps Utils Clustering 显示 InfoWindow [英] Android Maps Utils Clustering show InfoWindow

查看:19
本文介绍了Android Maps Utils Clustering 显示 InfoWindow的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我打算使用 utils 库中提供的 google maps 标记集群,但 google 示例应用程序仅显示标记集群,而没有任何 infoWindow.我现在想知道,我不能显示 InfoWindow 吗?我希望 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. I am wondering now, am I not able to show a InfoWindow? I want the InfoWindow to be displayed on the marker like with a normal google maps marker, not on the cluster.

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

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.

此解决方案仅为标记实现了 InfoWindows.

This solution only implements InfoWindows for Markers.

它类似于为没有聚类的普通标记实现自定义 InfoWindowAdapter 的方式,但有一个额外的要求,即您保留对当前所选项目的引用,以便您可以从 MyItem 中获取标题和代码段 实例,因为 Marker 不像通常那样存储 Title 和 Snippet.

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.

请注意,由于所有数据都存储在 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.java,其中包括标题和代码段的额外字段:

First, the MyItem.java, which includes extra fields for Title and 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 类,其中包括为使用集群库添加的每个标记支持 InfoWindows 的所有功能:

Here is the full Activity class, which includes all of the functionality to support InfoWindows for each Marker added using the Cluster library:

Edit:添加了对处理 InfoWindow 上的单击事件的支持,使 Activity 实现了 OnClusterItemInfoWindowClickListener 并添加了 onClusterItemInfoWindowClick 回调.

Added support for handling click events on the InfoWindow, made the Activity implement OnClusterItemInfoWindowClickListener and added the onClusterItemInfoWindowClick callback.

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>

结果:

初始启动:

缩小,开始聚类:

再次缩小,更多聚类:

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

Then, zooming in, and clicking on an individual Marker:

然后点击另一个标记:

为了在自定义信息窗口周围显示语音气泡",使用 getInfoContents() 而不是 getInfoWindow():

In order to show the "speech bubble" around the custom InfoWindow, use getInfoContents() instead of 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;
    }
}

结果:

这篇关于Android Maps Utils Clustering 显示 InfoWindow的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆