Google 地图:每个标记都有不同的自定义信息窗口
Google Maps: Different CustomInfowindow for each marker
我有一个 android 应用程序,其中包含一个 MapsActivity 以使用 GoogleMaps 显示许多标记。
标记是通过时间戳对象创建的
时间戳对象属性
(double lat,lon;
int stepSum;
long timeMilli;
String state=null;)
存储在 Firebase 数据库中。
因此,我从数据库中检索每个时间戳,并尝试使用上述属性创建一个标记。我的问题是,当我单击一个标记时,显示的是自定义信息 window,但 所有标记都相同 。它应该为不同的标记显示不同的属性。
为什么会这样
在 drawMarkers()
方法中,我在创建新标记时实例化了一个单独的信息 window 并将该信息 window 设置为
mMap.setInfoWindowAdapter(infoWindow);
的 GoogleMap 对象。
我的结果是 mMap.setInfoWindowAdapter(infoWindow);
被调用的次数与创建标记的次数一样多,最后只有最后一个信息 window 幸存下来。这就是问题所在,但我无法找到解决方案。
如何实现信息window 当我单击一个标记时它会显示某种数据,而当我单击另一个标记时它会显示不同类型的数据(相同的布局,不同的属性)。
一个有效的例子也可以。
CustomInfoWindow class
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 有关信息 windows 但无法解决我的问题。
希望此 example 将帮助您将其用作简单的 xml 布局。
请记住,如果您希望按钮处于可用状态,请记住按钮将无法正常工作,textview 将当场完成您的要求,请遵循 chose007 example.
我的解决方案
- 创建一个扩展 GoogleMap.InfoWindowAdapter 的 class。那将是整个地图的自定义信息窗口。
- 在 onMapReady() 内部,将您的 customInfoWindow 对象的实现设置为 GoogleMap 对象。这将是用户单击地图上的标记时显示的唯一信息窗口。
- 最后,在 onMapReady() 方法内部也将 OnMarkerClickListener 设置为 GoogleMap 对象。您对 GoogleMap.OnMarkerClickListener.onMarkerClick(Marker marker) 的实现只会 更改信息窗口的内容 (更改信息窗口对象的属性,随心所欲地调用它),具体取决于哪个单击标记。
我有一个 android 应用程序,其中包含一个 MapsActivity 以使用 GoogleMaps 显示许多标记。
标记是通过时间戳对象创建的
时间戳对象属性
(double lat,lon;
int stepSum;
long timeMilli;
String state=null;)
存储在 Firebase 数据库中。
因此,我从数据库中检索每个时间戳,并尝试使用上述属性创建一个标记。我的问题是,当我单击一个标记时,显示的是自定义信息 window,但 所有标记都相同 。它应该为不同的标记显示不同的属性。
为什么会这样
在 drawMarkers()
方法中,我在创建新标记时实例化了一个单独的信息 window 并将该信息 window 设置为
mMap.setInfoWindowAdapter(infoWindow);
的 GoogleMap 对象。
我的结果是 mMap.setInfoWindowAdapter(infoWindow);
被调用的次数与创建标记的次数一样多,最后只有最后一个信息 window 幸存下来。这就是问题所在,但我无法找到解决方案。
如何实现信息window 当我单击一个标记时它会显示某种数据,而当我单击另一个标记时它会显示不同类型的数据(相同的布局,不同的属性)。
一个有效的例子也可以。
CustomInfoWindow class
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 有关信息 windows 但无法解决我的问题。
希望此 example 将帮助您将其用作简单的 xml 布局。 请记住,如果您希望按钮处于可用状态,请记住按钮将无法正常工作,textview 将当场完成您的要求,请遵循 chose007 example.
我的解决方案
- 创建一个扩展 GoogleMap.InfoWindowAdapter 的 class。那将是整个地图的自定义信息窗口。
- 在 onMapReady() 内部,将您的 customInfoWindow 对象的实现设置为 GoogleMap 对象。这将是用户单击地图上的标记时显示的唯一信息窗口。
- 最后,在 onMapReady() 方法内部也将 OnMarkerClickListener 设置为 GoogleMap 对象。您对 GoogleMap.OnMarkerClickListener.onMarkerClick(Marker marker) 的实现只会 更改信息窗口的内容 (更改信息窗口对象的属性,随心所欲地调用它),具体取决于哪个单击标记。