You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中Firebase异步请求后无法更新GoogleMap信息窗口内容

问题解决:Google Map InfoWindow 首次加载不显示Firebase数据

问题原因

你的代码核心问题是异步请求的执行时机和InfoWindow的渲染机制不匹配:

  • Firebase的get()方法是异步执行的,getInfoWindow()会先返回布局View,此时异步请求还没完成,控件赋值时用的是静态变量的初始值(首次为null/默认内容)。
  • 第二次点击Marker时,之前的异步请求已经完成,静态变量被赋值,所以能显示数据,但静态变量会被所有Marker共享,后续还会出现数据错乱的问题。

解决方案步骤

  • 移除静态变量,改用局部变量或内部类持有数据,避免多Marker间的数据污染。
  • 将控件赋值逻辑移到Firebase请求的onComplete回调内部,确保数据加载完成后再更新控件。
  • 数据加载完成后调用marker.showInfoWindow()强制刷新InfoWindow,因为InfoWindow一旦渲染就不会自动更新。
  • 增加异常处理,比如图片为null时设置默认占位图,避免崩溃。

修改后的完整代码

public class MyInfoWindowAdapter implements GoogleMap.InfoWindowAdapter {

    private final Context context;

    public MyInfoWindowAdapter(Context context) {
        this.context = context;
    }

    @Override
    public View getInfoWindow(@NonNull Marker marker) {
        if (!"Este es mi perfil".equals(marker.getTitle())) {
            // 加载自定义布局
            View infoView = LayoutInflater.from(context).inflate(R.layout.custom_info, null);
            TextView titleMod = infoView.findViewById(R.id.title_mod);
            TextView snippMod = infoView.findViewById(R.id.snipp_mod);
            ImageView imagenMod = infoView.findViewById(R.id.imagen_mod);

            // 初始化显示加载占位符
            snippMod.setText("加载中...");
            imagenMod.setImageResource(R.drawable.default_profile); // 替换成你的默认图片

            LatLng posicionMarker = marker.getPosition();
            String idLocation = String.valueOf(posicionMarker.latitude).replace(".", "") + "_" +
                    String.valueOf(posicionMarker.longitude).replace(".", "");

            // 第一次请求获取chismesinfo数据
            DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("chismesinfo");
            databaseReference.child(idLocation).get().addOnCompleteListener(task -> {
                if (task.isSuccessful() && task.getResult() != null) {
                    DataSnapshot snapshot = task.getResult();
                    String descripcion = snapshot.child("descripcion").getValue(String.class);
                    String userId = snapshot.child("user").getValue(String.class);

                    if (userId != null) {
                        // 第二次请求获取用户数据
                        DatabaseReference usersReference = FirebaseDatabase.getInstance().getReference("users");
                        usersReference.child(userId).get().addOnCompleteListener(userTask -> {
                            if (userTask.isSuccessful() && userTask.getResult() != null) {
                                DataSnapshot userSnapshot = userTask.getResult();
                                String username = userSnapshot.child("name").getValue(String.class);
                                String foto = userSnapshot.child("profile").getValue(String.class);

                                // 更新控件内容
                                snippMod.setText(descripcion != null ? descripcion : "暂无描述");
                                titleMod.setText(username != null ? username : "匿名用户");

                                // 处理图片加载
                                if (foto != null) {
                                    try {
                                        byte[] imageAsByte = Base64.decode(foto, Base64.DEFAULT);
                                        Bitmap bitmap = BitmapFactory.decodeByteArray(imageAsByte, 0, imageAsByte.length);
                                        imagenMod.setImageBitmap(bitmap);
                                    } catch (IllegalArgumentException e) {
                                        imagenMod.setImageResource(R.drawable.default_profile);
                                    }
                                } else {
                                    imagenMod.setImageResource(R.drawable.default_profile);
                                }

                                // 刷新InfoWindow,确保更新后的内容显示
                                marker.showInfoWindow();
                            } else {
                                // 请求失败时显示默认内容
                                snippMod.setText("加载失败");
                                marker.showInfoWindow();
                            }
                        });
                    } else {
                        snippMod.setText("用户信息缺失");
                        marker.showInfoWindow();
                    }
                } else {
                    snippMod.setText("加载失败");
                    marker.showInfoWindow();
                }
            });

            return infoView;
        }
        return null;
    }

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

关键优化点说明

  1. 移除静态变量:所有数据变量改为局部变量,避免多Marker间的数据干扰。
  2. 异步回调内更新控件:确保只有当Firebase数据加载完成后,才更新控件内容。
  3. 强制刷新InfoWindow:调用marker.showInfoWindow()触发重新渲染,让更新后的内容显示出来。
  4. 异常处理:增加图片解码异常、请求失败的处理逻辑,提升稳定性。
  5. 加载占位符:初始显示加载状态,提升用户体验。

内容的提问来源于stack exchange,提问作者Dp258

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 10:53:30