[英]How do I show a MapView or GoogleMap in a DialogFragment?
我有一个创建为 dialogFragment 的对话框,它有自己的 XML 布局。 是否可以在 DialogFragment 中嵌入地图并引用它,以便我可以更新它的位置?
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.andrew.neighborlabour.CreateJobDialog">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:orientation="horizontal">
<TextView
android:id="@+id/tvTitle"
android:text="Create Job"
android:textAppearance="@color/colorPrimaryDark"
android:textSize="24dp"
android:padding="20dp"
android:lines="2"
android:layout_gravity="left"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
<ScrollView android:id="@+id/ScrollView01"
android:layout_width="fill_parent"
android:layout_height="400dp">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:paddingBottom="20dp"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Address"
android:id="@+id/etAddress"/>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="200dp"
android:id="@+id/map"
tools:context=".MapsActivity"
android:name="com.google.android.gms.maps.SupportMapFragment" />
</LinearLayout>
</ScrollView>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Create Job"
android:id="@+id/btCreate"
android:onClick="Create"/>
</LinearLayout>
进入 XML 我可以看到地图,但我不确定如何从我的 Java 代码中与它进行交互。
对话片段:
public class CreateJobDialog extends DialogFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog_create_job, container, false);
return view;
}
}
创建对话框:
CreateJobDialog createJobDialog = new CreateJobDialog();
createJobDialog.show(this.getFragmentManager(), "NoticeDialogFragment");
这是非常标准的,只需使用getMapAsync()
方法来获取对 Google 地图的引用。
唯一令人惊讶的是我不得不在 DialogFragment 代码中使用getFragmentManager()
而不是getChildFragmentManager()
。 通常在 Fragment 中嵌套 SupportMapFragment 时,您需要使用子 FragmentManager,但显然 DialogFragment 不同。
这是 DialogFragment 代码:
import android.support.v4.app.DialogFragment;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapDialogFragment extends DialogFragment
implements OnMapReadyCallback{
GoogleMap mMap;
public MapDialogFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_map_dialog, container, false);
SupportMapFragment mapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
return rootView;
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
LatLng latLng = new LatLng(37.7688472,-122.4130859);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,11));
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Position");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mMap.addMarker(markerOptions);
}
}
启动 DialogFragment:
new MapDialogFragment().show(getSupportFragmentManager(), null);
结果:
我会在@Daniel Nugent 的答案中添加onDestroyView()
方法中以下代码的实现。
@Override
public void onDestroyView() {
super.onDestroyView();
assert getFragmentManager() != null;
Fragment fragment = (getFragmentManager().findFragmentById(R.id.map));
FragmentTransaction ft = Objects.requireNonNull(getActivity()).getSupportFragmentManager().beginTransaction();
ft.remove(fragment);
ft.commit();
}
我按照他的回答步骤操作,但标记为“致命例外”。 当打开>关闭>返回打开'DialogFragment'。
Caused by: android.view.InflateException: Binary XML file line #44: Error inflating class fragment
Caused by: java.lang.IllegalArgumentException: Binary XML file line #44: Duplicate id 0x7f0900c3, tag null, or parent id 0x7f090067 with another fragment for com.google.android.gms.maps.SupportMapFragment.
注意:对于与我有相同问题的其他人来说,遵循这个答案可能会很有用。 我不把我的观察放在评论中,因为我不遵守 50 声望点。
好吧,由于带有 google api 的多地图,我遇到了一些问题。 所以我认为完整的可重用对话框使用的完整答案应该是这样的(基于以前的答案)。
public class MapDialogFragment extends DialogFragment
implements OnMapReadyCallback{
GoogleMap mMap;
public MapDialogFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_map_edit_location, container, false);
return rootView;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
FragmentManager fm = getChildFragmentManager();
SupportMapFragment mapFragment = (SupportMapFragment) fm.findFragmentByTag("mapFragment");
if (mapFragment == null) {
mapFragment = new SupportMapFragment();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.mapFragmentContainer, mapFragment, "mapFragment");
ft.commit();
fm.executePendingTransactions();
}
mapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
LatLng latLng = new LatLng(37.7688472,-122.4130859);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,11));
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Position");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mMap.addMarker(markerOptions);
}
}
然后是带有谷歌地图的 xml 文件(请注意,我们仅使用父布局以避免在另一个片段中膨胀)。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mapFragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
</LinearLayout>
来自我的片段的调用。
new MapDialogFragment().show(getActivity().getSupportFragmentManager(), null);
希望它能帮助一些人搜索在多地图上下文中甚至工作的对话框。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.