【问题标题】:Google Maps: Different CustomInfowindow for each marker谷歌地图:不同的自定义信息窗口 foreach 标记
【发布时间】:2018-01-19 16:30:38
【问题描述】:

我有一个 Android 应用程序,其中包含 MapsActivity 以使用 GoogleMaps 显示许多标记。

标记是通过 Timestamp 对象创建的

时间戳对象属性

(double lat,lon;
    int stepSum;
    long timeMilli;
    String state=null;)

存储在 Firebase 数据库中。

所以我从数据库中检索每个时间戳,并尝试使用上面的那些属性创建一个标记。我的问题是,当我单击标记时,会显示自定义信息窗口,但 所有标记都相同。它应该为不同的标记显示不同的属性。

为什么会这样

drawMarkers() 方法中,我在创建新标记时实例化一个单独的信息窗口,并将该信息窗口设置为 带有mMap.setInfoWindowAdapter(infoWindow); 的 GoogleMap 对象。

我的结果mMap.setInfoWindowAdapter(infoWindow);被调用的次数与创建标记的次数一样多,最后只有最后一个信息窗口幸存下来。这就是问题所在,但我无法找到解决方案。

如何实现一个信息窗口,当我单击一个标记时,它会显示某种数据,而当我单击另一个标记时,它会显示不同类型的数据(相同的布局,不同的属性)。

一个有效的例子也可以。

CustomInfoWindow 类

 private class CustomInfoWindow implements GoogleMap.InfoWindowAdapter{

    private String title=null,hour=null,state=null;
    private int steps=0;

    public CustomInfoWindow(){}

    public CustomInfoWindow(String title, String hour, String state, int steps) {
        this.title = title;
        this.hour = hour;
        this.state = state;
        this.steps = steps;
    }

    @Override
    public View getInfoWindow(Marker marker) {
        return null;
    }

    public void setState(String state) {
        this.state = state;
    }

    @Override
    public View getInfoContents(Marker marker) {
        LayoutInflater inflater = LayoutInflater.from(getApplicationContext());
        View root = inflater.inflate(R.layout.marker_infowindow,null);
        TextView titleTextView = (TextView) root.findViewById(R.id.infowindow_title);
        TextView hourTextView = (TextView) root.findViewById(R.id.infowindow_hour);
        TextView stepsTextView = (TextView) root.findViewById(R.id.infowindow_steps);
        TextView stateTextView = (TextView) root.findViewById(R.id.infowindow_state);
        titleTextView.setText(title);
        if (state!=null){
            stateTextView.setText(getApplicationContext().getString(R.string.state)+" "+state);
            stateTextView.setVisibility(View.VISIBLE);
        }
        hourTextView.setText(getApplicationContext().getString(R.string.time)+" "+hour);
        stepsTextView.setText(getApplicationContext().getString(R.string.steps_so__far)+" "+steps);
        return root;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public void setHour(String hour) {
        this.hour = hour;
    }

    public void setSteps(int steps) {
        this.steps = steps;
    }
}

标记的绘制方式

private void drawMarkers(Calendar c){
    String userId = this.user.getAccount().getId();
    int year = c.get(Calendar.YEAR);
    int month = c.get(Calendar.MONTH);
    int dayOfMonth = c.get(Calendar.DAY_OF_MONTH);

    final DatabaseReference timestampRef = FirebaseDatabase.getInstance().getReference()
            .child(FirebaseConstant.TIMESTAMPS.toString());
    timestampRef.child(userId).child(""+year).child(""+month).child(""+dayOfMonth)
            .addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    long childCounter=0;
                    for (DataSnapshot timestampSnapshot:dataSnapshot.getChildren()){
                        CustomInfoWindow infoWindow=new CustomInfoWindow();
                        Timestamp temp = timestampSnapshot.getValue(Timestamp.class);
                        if (temp!=null){
                            infoWindow.setTitle(getString(R.string.todays_timestamp));
                            infoWindow.setHour(getFormatedHourFromTimeMilli(temp.getTimeMilli()));
                            infoWindow.setSteps(temp.getStepSum());
                            if (temp.getState()!=null){
                                infoWindow.setState(temp.getState());
                            }
                            mMap.setInfoWindowAdapter(infoWindow);
                            drawTimestamp(temp);
                            infoWindow=null;
                        }
                    }
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {}
            });
}

我已阅读 google's tutorial 关于信息窗口的信息,但无法解决我的问题。

【问题讨论】:

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


    【解决方案1】:

    希望example 能帮助您将其用作简单的 xml 布局。 请记住按钮不起作用,如果您想让按钮处于可用状态,只需 textview 即可完成您的要求,请关注chose007 example

    【讨论】:

    • 感谢 Nowshad 所做的努力,但我的问题不是如何实现自定义信息窗口,而是如何为每个标记设置一个唯一的信息窗口。
    【解决方案2】:

    我的解决方案

    • 创建一个扩展 GoogleMap.InfoWindowAdapter 的类。这将是整个地图的自定义信息窗口。
    • 在 onMapReady() 内部将您的 customInfoWindow 对象的实现设置为 GoogleMap 对象。这将是用户单击地图上的标记时显示的唯一一个信息窗口。
    • 最后,在 onMapReady() 方法内部也为 GoogleMap 对象设置了一个 OnMarkerClickListener。您对 GoogleMap.OnMarkerClickListener.onMarkerClick(Marker marker) 的实现只会 更改内容(更改 infowindow 对象的属性,随意调用它),具体取决于单击的标记.

    【讨论】:

      猜你喜欢
      • 2019-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-13
      • 2015-09-07
      • 2011-08-21
      • 1970-01-01
      相关资源
      最近更新 更多