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

Android中在Material Dialog内显示Google Map遇SupportFragmentManager访问问题

解决Material Dialog中无法访问SupportFragmentManager加载Google Map的问题

你的核心问题在于**AddressViewDialog继承自MaterialDialog.Builder,而这个类既不是Fragment也不是AppCompatActivity的子类**,所以直接调用getChildFragmentManager()或者getSupportFragmentManager()肯定会报错——这些方法只有在Fragment或支持库的Activity中才存在。

下面给你两种可行的解决方案,优先推荐第一种(用MapView),因为Dialog中嵌套Fragment容易出现生命周期管理的问题。


方案一:使用MapView替代SupportMapFragment

MapView是专门为在非Fragment/Activity的容器中展示地图设计的,更适配Dialog这种场景。

步骤1:修改布局文件(替换fragment为MapView)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal"
    android:orientation="vertical"
    android:layout_margin="@dimen/activity_horizontal_margin">

    <com.google.android.gms.maps.MapView
        android:id="@+id/map_view"
        android:layout_width="match_parent"
        android:layout_height="250dp" />
</LinearLayout>

步骤2:修改Dialog类代码

需要同步MapView的生命周期方法,确保地图功能正常运行:

public class AddressViewDialog extends MaterialDialog.Builder implements OnMapReadyCallback {
    private MaterialDialog reviewDialog;
    private double latitude = 23.0;
    private double longitude = 90.0;
    private MapView mMapView;
    private GoogleMap mMap;
    private Context context;

    public AddressViewDialog(Context context) {
        super(context);
        this.context = context;
        initializeView();
    }

    public void initializeView() {
        reviewDialog = new MaterialDialog.Builder(context)
                .title(R.string.request_to_introduce)
                .customView(R.layout.dialog_pending_introducer_review, true)
                .show();

        View v = reviewDialog.getCustomView();
        mMapView = v.findViewById(R.id.map_view);

        // 初始化MapView
        Bundle mapViewBundle = new Bundle();
        mMapView.onCreate(mapViewBundle);
        mMapView.getMapAsync(this);

        // 根据经纬度控制地图显示状态
        mMapView.setVisibility((latitude != 0.0 && longitude != 0.0) ? View.VISIBLE : View.GONE);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        LatLng currentLoc = new LatLng(latitude, longitude);
        mMap.addMarker(new MarkerOptions().position(currentLoc).title("My Location"));
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLoc, 14.0f));
    }

    // 同步MapView的生命周期方法,需要在调用Dialog的Activity中对应调用
    public void onStart() {
        mMapView.onStart();
    }

    public void onResume() {
        mMapView.onResume();
    }

    public void onPause() {
        mMapView.onPause();
    }

    public void onStop() {
        mMapView.onStop();
    }

    public void onDestroy() {
        mMapView.onDestroy();
    }
}

补充说明

在调用这个Dialog的Activity中,记得同步触发MapView的生命周期,比如:

AddressViewDialog dialog = new AddressViewDialog(this);

@Override
protected void onResume() {
    super.onResume();
    dialog.onResume();
}

@Override
protected void onPause() {
    super.onPause();
    dialog.onPause();
}

方案二:使用DialogFragment封装(如果坚持用SupportMapFragment)

如果你一定要用SupportMapFragment,可以把Dialog改成DialogFragment,这样就能正常获取FragmentManager了。

步骤1:创建DialogFragment子类

public class AddressViewDialogFragment extends DialogFragment implements OnMapReadyCallback {
    private double latitude = 23.0;
    private double longitude = 90.0;
    private SupportMapFragment mMapFragment;
    private GoogleMap mMap;

    // 静态方法传参,避免直接实例化
    public static AddressViewDialogFragment newInstance(double lat, double lng) {
        AddressViewDialogFragment fragment = new AddressViewDialogFragment();
        Bundle args = new Bundle();
        args.putDouble("lat", lat);
        args.putDouble("lng", lng);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            latitude = getArguments().getDouble("lat");
            longitude = getArguments().getDouble("lng");
        }
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.dialog_pending_introducer_review, container, false);
        mMapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.fragment);
        
        // 控制地图显示
        if (latitude != 0.0 && longitude != 0.0) {
            mMapFragment.getView().setVisibility(View.VISIBLE);
            mMapFragment.getMapAsync(this);
        } else {
            mMapFragment.getView().setVisibility(View.GONE);
        }
        return view;
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        return new MaterialDialog.Builder(requireContext())
                .title(R.string.request_to_introduce)
                .setView(getView())
                .create();
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        LatLng currentLoc = new LatLng(latitude, longitude);
        mMap.addMarker(new MarkerOptions().position(currentLoc).title("My Location"));
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLoc, 14.0f));
    }
}

步骤2:在Activity中显示DialogFragment

// 传入经纬度并显示对话框
AddressViewDialogFragment dialog = AddressViewDialogFragment.newInstance(23.0, 90.0);
dialog.show(getSupportFragmentManager(), "AddressDialog");

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:51:17