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
相关产品推荐
相关产品推荐

