Android地图utils的聚类显示信息窗口 [英] Android Maps Utils Clustering show InfoWindow

查看:336
本文介绍了Android地图utils的聚类显示信息窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我计划使用谷歌地图标记聚集在utils的库中可用,但谷歌的示例应用程序只显示标记集群,没有任何信息窗口。我想知道现在,我是不能够显示信息窗口?我想信息窗口能与正常的谷歌地图标记显示在标记一样,群集不上了。

在code,我有:(从谷歌的例子)

 公共类BigClusteringDemoActivity扩展FragmentActivity {
    私人ClusterManager< MyItem> mClusterManager;
    私人GoogleMap的MMAP;

    私人无效readItems(){
        InputStream中的InputStream = getResources()openRawResource(R.raw.radar_search)。
        名单< MyItem>项目=新MyItemReader()读取(InputStream的)。

        的for(int i = 0;我小于10;我++){
            双偏心= I / 60D;
            对于(MyItem项目:项目){
                经纬度位置= item.getPosition();
                双纬度= position.latitude +偏移;
                双LNG = position.longitude +偏移;
                MyItem offsetItem =新MyItem(纬度,经度);
                mClusterManager.addItem(offsetItem);
            }
        }
    }

    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.map);

        mClusterManager =新ClusterManager<>(这一点,MMAP);

        MMAP =((SupportMapFragment)getSupportFragmentManager()findFragmentById(R.id.map)。)的GetMap()。

        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(新经纬度(51.503186,-0.126446),10));
        mMap.setOnCameraChangeListener(mClusterManager);

        readItems();
    }

}
 

解决方案

下面是一个基于<一个简化的和略作修改的解决方案href="http://stackoverflow.com/questions/25968486/how-to-add-info-window-for-clustering-marker-in-android/25969059#25969059">this回答。需要注意的是链接的答案实现了一个信息窗口为标记和集群。

该解决方案不仅实现了信息窗口的标记。

这是类似于你将如何实现自定义InfoWindowAdapter正常标记,没有集群,但随着附加要求你保持一个参考当前选定的项目,这样你可以得到的标题和摘录从它的 MyItem 情况下,由于标记不存储标题和片段,因为它通常一样。

请注意,由于所有的数据都存储在 MyItem 引用,它更容易为你想扩展的信息窗口的每个显示尽可能多的数据类型的功能标记。

首先,MyItem.java,其中包括额外的标题和摘录领域:

 公共类MyItem实现ClusterItem {
    私人最终经纬度mPosition;
    私人最终字符串mTitle;
    私人最终字符串mSnippet;

    公共MyItem(双纬度,双经度,串T,String s)将{
        mPosition =新的经纬度(纬度,经度);
        mTitle = T;
        mSnippet =秒;
    }

    @覆盖
    公共经纬度为getPosition(){
        返回mPosition;
    }

    公共字符串的getTitle(){
        返回mTitle;
    }

    公共字符串getSnippet(){
        返回mSnippet;
    }
}
 

下面是完整的活动类,它包含了所有支持信息窗口每个标记的功能加入使用群集库:

编辑:增加了对处理点击事件的信息窗口的支持,取得了活动实施 OnClusterItemInfoWindowClickListener 并添加了 onClusterItemInfoWindowClick 回电话。

 公共类MapsActivity扩展AppCompatActivity
        实现ClusterManager.OnClusterItemInfoWindowClickListener&LT; MyItem&GT; {

    私人ClusterManager&LT; MyItem&GT; mClusterManager;
    私人MyItem clickedClusterItem;
    私人GoogleMap的MMAP;

    @覆盖
    保护无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);

        的setContentView(R.layout.activity_maps);

        setUpMapIfNeeded();
    }

    @覆盖
    保护无效onResume(){
        super.onResume();
        setUpMapIfNeeded();
    }


    私人无效setUpMapIfNeeded(){
        //做一个空检查确认,我们还没有实例化的地图。
        如果(MMAP == NULL){
            //尝试获取来自SupportMapFragment地图。
            MMAP =((SupportMapFragment)getSupportFragmentManager()。findFragmentById(R.id.map))
                    .getMap();

            //检查如果我们成功取得地图。
            如果(MMAP!= NULL){
                setUpMap();
            }

        }
    }

    私人无效setUpMap(){

        mMap.getUiSettings()setMapToolbarEnabled(真)。
        mMap.getUiSettings()setZoomControlsEnabled(真)。
        mMap.setMyLocationEnabled(真正的);
        mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);

        mClusterManager =新ClusterManager&LT;&GT;(这一点,MMAP);

        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(新经纬度(37.779977,-122.413742),10));

        mMap.setOnCameraChangeListener(mClusterManager);
        mMap.setOnMarkerClickListener(mClusterManager);

        mMap.setInfoWindowAdapter(mClusterManager.getMarkerManager());

        mMap.setOnInfoWindowClickListener(mClusterManager); //添加
        mClusterManager.setOnClusterItemInfoWindowClickListener(本); //添加

        mClusterManager
                .setOnClusterItemClickListener(新ClusterManager.OnClusterItemClickListener&其中; MyItem&GT;(){
                    @覆盖
                    公共布尔onClusterItemClick(MyItem项目){
                        clickedClusterItem =项目;
                        返回false;
                    }
                });



        为addItems();

        mClusterManager.getMarkerCollection()。setOnInfoWindowAdapter(
                新MyCustomAdapterForItems());

    }

    私人无效为addItems(){

        双纬度= 37.779977;
        双东经= -122.413742;
        的for(int i = 0;我小于10;我++){
            双偏心= I / 60D;

            双纬度=北纬+偏移;
            双LNG =经度+偏移;
            MyItem offsetItem =新MyItem(纬度,经度,标题+ i + 1的片段+ I + 1);
            mClusterManager.addItem(offsetItem);

        }

    }

    //添加编辑
    @覆盖
    公共无效onClusterItemInfoWindowClick(MyItem myItem){

        //集群项目信息窗口点击,设置标题为行动
        意图I =新的意图(这一点,OtherActivity.class);
        i.setAction(myItem.getTitle());
        startActivity(ⅰ);

        //你可能需要做不同的事情为每个信息窗口:
        如果(myItem.getTitle()。等于(有些题)){

            //做具体到这一信息窗口的东西....

        }

    }

    公共类MyCustomAdapterForItems实现GoogleMap.InfoWindowAdapter {

        私人最终查看myContentsView;

        MyCustomAdapterForItems(){
            myContentsView = getLayoutInflater()。膨胀(
                    R.layout.info_window,NULL);
        }
        @覆盖
        公共查看getInfoWindow(标记标记){

            TextView的tvTitle =((TextView中)myContentsView
                    .findViewById(R.id.txtTitle));
            TextView的tvSnippet =((TextView中)myContentsView
                    .findViewById(R.id.txtSnippet));

            tvTitle.setText(clickedClusterItem.getTitle());
            tvSnippet.setText(clickedClusterItem.getSnippet());

            返回myContentsView;
        }

        @覆盖
        公共查看getInfoContents(标记标记){
            返回null;
        }
    }
}
 

info_window.xml:

 &LT; XML版本=1.0编码=UTF-8&GT?;
&LT; LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent
    机器人:填充=20dp
    机器人:方向=垂直
    机器人:后台=#000000&GT;

    &LT;的TextView
        机器人:ID =@ + ID / txtTitle
        机器人:文字颜色=#D3649F
        机器人:TEXTSTYLE =黑体
        机器人:layout_width =WRAP_CONTENT
        机器人:layout_height =WRAP_CONTENT/&GT;

    &LT;的TextView
        机器人:ID =@ + ID / txtSnippet
        机器人:文字颜色=#D3649F
        机器人:layout_width =WRAP_CONTENT
        机器人:layout_height =WRAP_CONTENT/&GT;

&LT; / LinearLayout中&GT;
 

结果:

初​​始启动:

放大出来,开始集群:

放大出来了,更多的集群:

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

然后点击另外一个标记:

编辑:为了显示讲话泡沫周围的自定义信息窗口,使用 getInfoContents()而不是 getInfoWindow()

 公共类MyCustomAdapterForItems实现GoogleMap.InfoWindowAdapter {

    私人最终查看myContentsView;

    MyCustomAdapterForItems(){
        myContentsView = getLayoutInflater()。膨胀(
                R.layout.info_window,NULL);
    }

    @覆盖
    公共查看getInfoWindow(标记标记){
        返回null;
    }

    @覆盖
    公共查看getInfoContents(标记标记){

        TextView的tvTitle =((TextView中)myContentsView
                .findViewById(R.id.txtTitle));
        TextView的tvSnippet =((TextView中)myContentsView
                .findViewById(R.id.txtSnippet));

        tvTitle.setText(clickedClusterItem.getTitle());
        tvSnippet.setText(clickedClusterItem.getSnippet());

        返回myContentsView;
    }
}
 

结果:

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.

This solution only implements InfoWindows for Markers.

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.

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.

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

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

Edit: 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:

<?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():

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:

这篇关于Android地图utils的聚类显示信息窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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