如何将Firebase用户数据展示到谷歌地图自定义Info Window中
解决方案
适配器选择说明
FirebaseRecyclerAdapter是专为RecyclerView列表场景设计的适配器,你的需求是为地图Marker的信息窗口绑定数据,不需要使用该组件,直接使用你已实现的自定义InfoWindowAdapter即可。
实现步骤
1. 创建用户信息实体类
首先新建UserInfo.java对应Firebase中Users节点的数据结构,注意字段要和数据库字段映射匹配,Firebase序列化必须保留空构造方法:
import com.google.firebase.database.PropertyName; public class UserInfo { @PropertyName("Alert Level") private String alertLevel; @PropertyName("Emergency Type") private String emergencyType; private String name; // 其他需要的字段按需添加 // 空构造方法不可省略 public UserInfo() {} // 对应Getter方法 public String getAlertLevel() { return alertLevel; } public String getEmergencyType() { return emergencyType; } public String getName() { return name; } }
2. 调整onMapReady逻辑
InfoWindowAdapter全局只需设置一次,不要重复在子节点回调中设置;同时在获取到位置数据后,关联查询对应用户的详情信息,将用户对象存入Marker的Tag属性中:
private GoogleMap mMap; @Override public void onMapReady(@NonNull GoogleMap googleMap) { mMap = googleMap; // 全局仅设置一次信息窗口适配器 mMap.setInfoWindowAdapter(new InfoWindowAdapter(Retrieve.this)); DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference(); DatabaseReference locationRef = rootRef.child("User Location"); DatabaseReference userRef = rootRef.child("Users"); locationRef.addChildEventListener(new ChildEventListener() { @Override public void onChildAdded(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) { // 获取位置对应的用户UID String uid = snapshot.getKey(); LocationSend send = snapshot.getValue(LocationSend.class); LatLng location = new LatLng(send.getLatitude(), send.getLongitude()); // 查询对应用户的详情数据 userRef.child(uid).addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { UserInfo user = snapshot.getValue(UserInfo.class); if(user != null){ Marker marker = mMap.addMarker(new MarkerOptions() .position(location)); // 将用户对象存入Marker的Tag,供信息窗口读取 marker.setTag(user); } } @Override public void onCancelled(@NonNull DatabaseError error) {} }); mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(location, 14F)); Log.d("TAG", "latitude, longitude"); notification(); } @Override public void onChildChanged(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) { LocationSend send = snapshot.getValue(LocationSend.class); notification(); // 如果需要同步更新Marker位置和信息,可以在这里找到对应Marker更新数据后刷新 } @Override public void onChildRemoved(@NonNull DataSnapshot snapshot) {} @Override public void onChildMoved(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {} @Override public void onCancelled(@NonNull DatabaseError error) {} }); }
3. 修改自定义InfoWindowAdapter
直接从Marker的Tag属性中读取用户数据,给对应控件赋值即可:
public class InfoWindowAdapter implements GoogleMap.InfoWindowAdapter{ Context context; public InfoWindowAdapter(Context context){ this.context = context; } @Nullable @Override public View getInfoWindow(@NonNull Marker marker) { View infoView = LayoutInflater.from(context).inflate(R.layout.infowindow, null); TextView title = infoView.findViewById(R.id.title); TextView alert = infoView.findViewById(R.id.alert); TextView type = infoView.findViewById(R.id.type); // 从Marker的Tag中取出用户信息 UserInfo user = (UserInfo) marker.getTag(); if(user != null){ title.setText(user.getName()); alert.setText("告警级别:" + user.getAlertLevel()); type.setText("紧急事件类型:" + user.getEmergencyType()); } return infoView; } @Nullable @Override public View getInfoContents(@NonNull Marker marker) { return null; } }
内容的提问来源于stack exchange,提问作者Rafael Campos
相关产品推荐
相关产品推荐

