碎片中的MapFragment,替代方法?

我需要你的帮助…我工作到3天。 我的应用程序正在使用碎片。 其中一个片段必须显示Android版Google地图V2 api中的地图。

目前,我正在使用MapFragment,但并不奇怪,片段中的片段不是一个好主意,但它起作用,地图正在显示,我可以编辑它,但是当我切换主片段并返回时。

由于:java.lang.IllegalArgumentException:二进制XML文件行#59:重复ID为0x7f070041,标记为null或父级ID为0x7f070040,另一个片段为com.google.android.gms.maps.MapFragment

在android.app.Activity.onCreateView(Activity.java:4252)

在android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:673)

这是当我去另一个片段,并返回到包含地图的那个原因。 我正在寻找,直到3天来解决这个问题,但没有很好的结果。

为了继续为你,我有一个活动,调用布局文件中包含一个MapFragment的片段。 如果你需要更多,只要问:)

谢谢

编辑:这是在主要活动中更改片段的代码

private void swtichFragment(Fragment fragment, Bundle bundle) { fragment.setBundle(this, bundle); FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.replace(R.id.rightFragmentPlaceHolder, fragment); fragmentTransaction.commit(); mRightFragment = fragment; } 

在你的Fragment的布局中使用MapView代替MapFragment。 记得调用MapView的生命周期方法:

  • 的onCreate(捆绑)
  • 的onResume()
  • 的onPause()
  • 的onDestroy()
  • 的onSaveInstanceState(捆绑)
  • onLowMemory()

如此处所述。

顺便说一句。 你不应该使用MapFragment,只能使用SupportMapFragment和支持库 。

编辑:

如果您切换到支持库,则可以使用评论#1中的代码: http : //code.google.com/p/gmaps-api-issues/issues/detail?id=5064 # c1

使用SupportMapFragment来克服这个错误:

在片段布局

 <fragment android:id="@+id/googleMap" android:name="com.google.android.gms.maps.SupportMapFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> 

在你的片段onCreateView

 SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.googleMap); if (mapFragment != null) { mapFragment.getMapAsync(this); } 

由于您的布局位于Fragment's布局中,因此SupportMapFragment是碎片的子布局。 因此,使用Fragment's FragmentManager getChildFragmentManager()

如此处所述

在片段(NestedFragment)中显示MapFragment:在这一点上,我相信你有

  1. 为清单添加了必要的权限
  2. 添加谷歌播放服务作为一个lib项目
  3. 清单文件中的API密钥。 4。

where.xml

  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:map="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" > <FrameLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1.03" android:name="com.google.android.gms.maps.SupportMapFragment" android:id="@+id/mapwhere" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout> 

类:

  public class WhereFragment extends SupportMapFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); View root = inflater.inflate(R.layout.where, null, false); initilizeMap(); return root; } private void initilizeMap() { mSupportMapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.mapwhere); if (mSupportMapFragment == null) { FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); mSupportMapFragment = SupportMapFragment.newInstance(); fragmentTransaction.replace(R.id.mapwhere, mSupportMapFragment).commit(); } if (mSupportMapFragment != null) { googleMap = mSupportMapFragment.getMap(); if (googleMap != null) googleMap.setOnMapClickListener(new OnMapClickListener() { @Override public void onMapClick(LatLng point) { //TODO: your onclick stuffs } }); } } } 

文档

嵌套片段您现在可以将片段embedded片段中。 这对于您想要将dynamic和可重用UI组件放入本身为dynamic且可重用的UI组件的各种情况很有用。 例如,如果使用ViewPager创build左右滑动并占用大部分屏幕空间的片段,则现在可以将片段插入到每个片段页面中。

要嵌套一个片段,只需在要添加片段的片段上调用getChildFragmentManager()即可。 这将返回一个FragmentManager,您可以像使用顶级活动一样使用FragmentManager来创build片段事务。 例如,下面是一些在现有的Fragment类中添加片段的代码:

片段videoFragment = new VideoPlayerFragment(); FragmentTransaction transaction = getChildFragmentManager()。beginTransaction(); transaction.add(R.id.video_fragment,videoFragment).commit(); 在嵌套片段中,可以通过调用getParentFragment()来获得父片段的引用。

Android支持库现在也支持嵌套片段,因此您可以在Android 1.6或更高版本上实现嵌套片段devise。

注意:当布局包含a时,不能将布局膨胀成片段。 只有在dynamic添加到片段时才支持嵌套片段。

来源: http : //developer.android.com/about/versions/android-4.2.html#NestedFragments

这也将解决:

  11-06 11:36:01.509: E/AndroidRuntime(6309): FATAL EXCEPTION: main 11-06 11:36:01.509: E/AndroidRuntime(6309): android.view.InflateException: Binary XML file line #9: Error inflating class fragment 11-06 11:36:01.509: E/AndroidRuntime(6309): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:710) 11-06 11:36:01.509: E/AndroidRuntime(6309): at android.view.LayoutInflater.rInflate(LayoutInflater.java:752) 11-06 11:36:01.509: E/AndroidRuntime(6309): at android.view.LayoutInflater.rInflate(LayoutInflater.java:760) 11-06 11:36:01.509: E/AndroidRuntime(6309): at android.view.LayoutInflater.rInflate(LayoutInflater.java:760) 11-06 11:36:01.509: E/AndroidRuntime(6309): at android.view.LayoutInflater.rInflate(LayoutInflater.java:760) 11-06 11:36:01.509: E/AndroidRuntime(6309): at android.view.LayoutInflater.rInflate(LayoutInflater.java:760) 11-06 11:36:01.509: E/AndroidRuntime(6309): at android.view.LayoutInflater.inflate(LayoutInflater.java:495) 11-06 11:36:01.509: E/AndroidRuntime(6309): at android.view.LayoutInflater.inflate(LayoutInflater.java:397) 11-06 11:36:01.509: E/AndroidRuntime(6309): at com.abc.android.ui.WhereFragment.onCreateView(WhereFragment.java:60) 11-06 11:36:01.509: E/AndroidRuntime(6309): at android.support.v4.app.Fragment.performCreateView(Fragment.java:1500) 11-06 11:36:01.509: E/AndroidRuntime(6309): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927) 11-06 11:36:01.509: E/AndroidRuntime(6309): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104) 11-06 11:36:01.509: E/AndroidRuntime(6309): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682) 11-06 11:36:01.509: E/AndroidRuntime(6309): at a ... 

在你的class级

  SupportMapFragment mSupportMapFragment; private GoogleMap googleMap; int ZOOM_LEVEL=15; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View mTrackView = inflater .inflate(R.layout.mylayout, container, false); mSupportMapFragment = SupportMapFragment.newInstance(); FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction(); fragmentTransaction.add(R.id.mapwhere, mSupportMapFragment); fragmentTransaction.commit(); return mTrackView; } @Override public void onStart() { // TODO Auto-generated method stub super.onStart(); if(mSupportMapFragment!=null){ googleMap = mSupportMapFragment.getMap(); if(googleMap!=null){ googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); googleMap.getUiSettings().setMyLocationButtonEnabled(false); googleMap.setMyLocationEnabled(false); CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom( new LatLng(12.12122, 17.22323), ZOOM_LEVEL); googleMap.animateCamera(cameraUpdate); } } } 

mylayout.xml

  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:map="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" > <FrameLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1.03" android:id="@+id/mapwhere" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout> 

经过很多错误我终于做到了,这里是我的MapView片段类:

 import android.content.Context; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.support.v4.app.Fragment; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Toast; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.GoogleMap.OnMapClickListener; import com.google.android.gms.maps.MapFragment; import com.google.android.gms.maps.model.BitmapDescriptorFactory; import com.google.android.gms.maps.model.CameraPosition; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.MarkerOptions; import com.serveroverload.yago.R; /** * @author 663918 * */ public class HomeFragment extends Fragment implements LocationListener { // Class to do operations on the Map GoogleMap googleMap; private LocationManager locationManager; public static Fragment newInstance() { return new HomeFragment(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.home_fragment, container, false); Bundle bdl = getArguments(); // setuping locatiomanager to perfrom location related operations locationManager = (LocationManager) getActivity().getSystemService( Context.LOCATION_SERVICE); // Requesting locationmanager for location updates locationManager.requestLocationUpdates( LocationManager.NETWORK_PROVIDER, 1, 1, this); // To get map from MapFragment from layout googleMap = ((MapFragment) getActivity().getFragmentManager() .findFragmentById(R.id.map)).getMap(); // To change the map type to Satellite // googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE); // To show our current location in the map with dot // googleMap.setMyLocationEnabled(true); // To listen action whenever we click on the map googleMap.setOnMapClickListener(new OnMapClickListener() { @Override public void onMapClick(LatLng latLng) { /* * LatLng:Class will give us selected position lattigude and * longitude values */ Toast.makeText(getActivity(), latLng.toString(), Toast.LENGTH_LONG).show(); } }); changeMapMode(3); // googleMap.setSatellite(true); googleMap.setTrafficEnabled(true); googleMap.setBuildingsEnabled(true); googleMap.setMyLocationEnabled(true); return v; } private void doZoom() { if (googleMap != null) { googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom( new LatLng(18.520430, 73.856744), 17)); } } private void changeMapMode(int mapMode) { if (googleMap != null) { switch (mapMode) { case 0: googleMap.setMapType(GoogleMap.MAP_TYPE_NONE); break; case 1: googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); break; case 2: googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE); break; case 3: googleMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN); break; case 4: googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); break; default: break; } } } private void createMarker(double latitude, double longitude) { // double latitude = 17.385044; // double longitude = 78.486671; // lets place some 10 random markers for (int i = 0; i < 10; i++) { // random latitude and logitude double[] randomLocation = createRandLocation(latitude, longitude); // Adding a marker MarkerOptions marker = new MarkerOptions().position( new LatLng(randomLocation[0], randomLocation[1])).title( "Hello Maps " + i); Log.e("Random", "> " + randomLocation[0] + ", " + randomLocation[1]); // changing marker color if (i == 0) marker.icon(BitmapDescriptorFactory .defaultMarker(BitmapDescriptorFactory.HUE_AZURE)); if (i == 1) marker.icon(BitmapDescriptorFactory .defaultMarker(BitmapDescriptorFactory.HUE_BLUE)); if (i == 2) marker.icon(BitmapDescriptorFactory .defaultMarker(BitmapDescriptorFactory.HUE_CYAN)); if (i == 3) marker.icon(BitmapDescriptorFactory .defaultMarker(BitmapDescriptorFactory.HUE_GREEN)); if (i == 4) marker.icon(BitmapDescriptorFactory .defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA)); if (i == 5) marker.icon(BitmapDescriptorFactory .defaultMarker(BitmapDescriptorFactory.HUE_ORANGE)); if (i == 6) marker.icon(BitmapDescriptorFactory .defaultMarker(BitmapDescriptorFactory.HUE_RED)); if (i == 7) marker.icon(BitmapDescriptorFactory .defaultMarker(BitmapDescriptorFactory.HUE_ROSE)); if (i == 8) marker.icon(BitmapDescriptorFactory .defaultMarker(BitmapDescriptorFactory.HUE_VIOLET)); if (i == 9) marker.icon(BitmapDescriptorFactory .defaultMarker(BitmapDescriptorFactory.HUE_YELLOW)); googleMap.addMarker(marker); // Move the camera to last position with a zoom level if (i == 9) { CameraPosition cameraPosition = new CameraPosition.Builder() .target(new LatLng(randomLocation[0], randomLocation[1])) .zoom(15).build(); googleMap.animateCamera(CameraUpdateFactory .newCameraPosition(cameraPosition)); } } } /* * creating random postion around a location for testing purpose only */ private double[] createRandLocation(double latitude, double longitude) { return new double[] { latitude + ((Math.random() - 0.5) / 500), longitude + ((Math.random() - 0.5) / 500), 150 + ((Math.random() - 0.5) * 10) }; } @Override public void onLocationChanged(Location location) { if (null != googleMap) { // To get lattitude value from location object double latti = location.getLatitude(); // To get longitude value from location object double longi = location.getLongitude(); // To hold lattitude and longitude values LatLng position = new LatLng(latti, longi); createMarker(latti, longi); // Creating object to pass our current location to the map MarkerOptions markerOptions = new MarkerOptions(); // To store current location in the markeroptions object markerOptions.position(position); // Zooming to our current location with zoom level 17.0f googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(position, 17f)); // adding markeroptions class object to the map to show our current // location in the map with help of default marker googleMap.addMarker(markerOptions); } } @Override public void onStatusChanged(String provider, int status, Bundle extras) { // TODO Auto-generated method stub } @Override public void onProviderEnabled(String provider) { // TODO Auto-generated method stub } @Override public void onProviderDisabled(String provider) { // TODO Auto-generated method stub } @Override public void onDestroyView() { // TODO Auto-generated method stub super.onDestroyView(); locationManager.removeUpdates(this); android.app.Fragment fragment = getActivity().getFragmentManager() .findFragmentById(R.id.map); if (null != fragment) { android.app.FragmentTransaction ft = getActivity() .getFragmentManager().beginTransaction(); ft.remove(fragment); ft.commit(); } } } 

我的Xml文件看起来像这样:

 <?xml version="1.0" encoding="utf-8"?> <fragment xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/map" android:name="com.google.android.gms.maps.MapFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> 

结果如下所示:

在这里输入图像说明

最重要的是要注意的是,不要混用app.Fragment与v4.Fragments其他应用程序将崩溃严重。

正如你所看到的,我已经使用app.Fragment来附加和删除我的MapView片段

希望它会帮助别人