Android – android.view.InflateException:二进制XML文件行#8:错误膨胀类的片段

我正在开发一个应用程序使用NavigationDrawerDrawerLayout和导航到不同的Fragments 。 当我调用Map_Fragment_Page ,应用程序崩溃,但不是第一次。 它第一次正确显示Map ,但之后,当我导航不同的片段,再次来到Map_Fragment_Page然后崩溃给出一个错误android.view.InflateException: Binary XML file line #8: Error inflating class fragment

我尝试了很多不同的解决方案,我也在Google搜索,但仍然没有得到所需的解决方案。 问题还没有解决。

howtoreach.xml

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:id="@+id/howtoreach_map" android:layout_width="match_parent" android:layout_height="match_parent" class="com.google.android.gms.maps.SupportMapFragment"/> </RelativeLayout> 

HowToReach.java

  package com.demo.map.howtoreach; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import android.support.v4.app.Fragment; import com.google.android.gms.maps.SupportMapFragment; 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.Marker; import com.google.android.gms.maps.model.MarkerOptions; import com.google.android.gms.maps.model.Polyline; import com.google.android.gms.maps.model.PolylineOptions; import com.demo.map.R; import android.app.ProgressDialog; import android.content.Context; import android.graphics.Color; import android.location.Criteria; import android.location.Location; import android.location.LocationManager; import android.os.Bundle; import android.os.Handler; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Toast; public class HowToReach extends Fragment { public static final String TAG = "fragment_5"; ProgressDialog dialog; GoogleMap googleMap; Marker marker; LocationManager locationManager; Location location; Criteria criteria; String provider; double latitude, longitude; public HowToReach(){} @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final View v = inflater.inflate(R.layout.howtoreach, container, false); dialog = ProgressDialog.show(getActivity(),"","Loading",true,false); int secondsDelayed = 4; new Handler().postDelayed(new Runnable() { public void run() { dialog.dismiss(); } }, secondsDelayed * 1000); try { // Loading map if (googleMap == null) { googleMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.howtoreach_map)).getMap(); googleMap.setMyLocationEnabled(true); locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE); criteria = new Criteria(); provider = locationManager.getBestProvider(criteria, true); location = locationManager.getLastKnownLocation(provider); latitude = location.getLatitude(); longitude = location.getLongitude(); // create marker marker = googleMap.addMarker(new MarkerOptions().position( new LatLng(latitude, longitude)).title("You are Here")); marker.setIcon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)); marker.showInfoWindow(); CameraPosition cameraPosition = new CameraPosition.Builder().target( new LatLng(latitude, longitude)).zoom(15).build(); googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); Polyline line = googleMap.addPolyline(new PolylineOptions() .add(new LatLng(latitude, longitude), new LatLng(18.520897,73.772396)) .width(2).color(Color.RED).geodesic(true)); marker = googleMap.addMarker(new MarkerOptions().position( new LatLng(18.520897, 73.772396)).title("DSK Ranwara Road")); marker.setIcon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)); // check if map is created successfully or not if (googleMap == null) { Toast.makeText(getActivity(),"Sorry! unable to create maps", Toast.LENGTH_SHORT).show(); } } } catch (Exception e) { e.printStackTrace(); } return v; } } 
 Yes.. I want Map inside a Fragment. 

你应该使用一个MapView

http://developer.android.com/reference/com/google/android/gms/maps/MapView.html

 public class HowToReach extends Fragment { MapView mapView; GoogleMap map; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment2, container, false); // Gets the MapView from the XML layout and creates it try { MapsInitializer.initialize(getActivity()); } catch (GooglePlayServicesNotAvailableException e) { Log.e("Address Map", "Could not initialize google play", e); } switch (GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity()) ) { case ConnectionResult.SUCCESS: Toast.makeText(getActivity(), "SUCCESS", Toast.LENGTH_SHORT).show(); mapView = (MapView) v.findViewById(R.id.map); mapView.onCreate(savedInstanceState); // Gets to GoogleMap from the MapView and does initialization stuff if(mapView!=null) { map = mapView.getMap(); map.getUiSettings().setMyLocationButtonEnabled(false); map.setMyLocationEnabled(true); CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(43.1, -87.9), 10); map.animateCamera(cameraUpdate); } break; case ConnectionResult.SERVICE_MISSING: Toast.makeText(getActivity(), "SERVICE MISSING", Toast.LENGTH_SHORT).show(); break; case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED: Toast.makeText(getActivity(), "UPDATE REQUIRED", Toast.LENGTH_SHORT).show(); break; default: Toast.makeText(getActivity(), GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity()), Toast.LENGTH_SHORT).show(); } // Updates the location and zoom of the MapView return v; } @Override public void onResume() { mapView.onResume(); super.onResume(); } @Override public void onDestroy() { super.onDestroy(); mapView.onDestroy(); } @Override public void onLowMemory() { super.onLowMemory(); mapView.onLowMemory(); } } 

fragment2.xml

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

更新:

 https://developers.google.com/android/reference/com/google/android/gms/maps/MapView#public-constructors 

getMap()已被弃用。 改用getMapAsync(OnMapReadyCallback) 。 回调方法为您提供了一个GoogleMap实例,保证它是非空的,可以使用。

所以如果它第二次打开片段后崩溃。 所有你需要的是在OnDestroy中

 @Override public void onDestroy() { super.onDestroy(); getFragmentManager().beginTransaction().remove(mapfragmentnamehere).commit(); } 

如果您使用支持片段,请进行所需的更改

我的经验是用xml-tag添加的片段

 <fragment>...</fragment>. 

这些片段通常是嵌套的,并且在父片段被破坏时不会被破坏。 一旦你试图再膨胀他们,你会得到基本上抱怨这个片段已经膨胀的异常。 因此,一旦父代碎片被破坏,我就会手动销毁我的嵌套碎片。 只需使用以下内容并根据需要进行调整即可。 此代码驻留在具有嵌套片段作为xml-tag的父代片段中。

 @Override public void onDestroy() { super.onDestroy(); final FragmentManager fragManager = this.getFragmentManager(); final Fragment fragment = fragManager.findFragmentById(/*id of fragment*/); if(fragment!=null){ fragManager.beginTransaction().remove(fragment).commit(); } } 

使用动态创建的片段,完全没有问题。 动态的意思是:你没有使用fragment-xml-tag

希望这可以帮助! 好编程!

我把这个放在我的片段里

 @Override public void onPause() { super.onPause(); getChildFragmentManager().beginTransaction() .remove(mMapFragment) .commit(); } 

它的工作,而不是替换到MapView。

改变这一点

 googleMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.howtoreach_map)).getMap(); 

 googleMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.howtoreach_map)).getMap(); 

在你的班级


  View mTrackView = inflater.inflate(R.layout.mylayout, container, false); SupportMapFragment mSupportMapFragment = SupportMapFragment.newInstance(); FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction(); fragmentTransaction.add(R.id.mapwhere, mSupportMapFragment); fragmentTransaction.commit(); if(mSupportMapFragment!=null){ googleMap = mSupportMapFragment.getMap(); if(googleMap!=null){ googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); googleMap.getUiSettings().setMyLocationButtonEnabled(false); googleMap.setMyLocationEnabled(false); if (mgpr_tracker.canGetLocation()) CURREN_POSITION = new LatLng(mgpr_tracker.getLatitude(), mgpr_tracker.getLongitude()); CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom( CURREN_POSITION, 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> 

正如你第一次告诉你的代码正在工作,所以我googlemap你再次调用你的地图你的googlemap对象不是null ,你没有正确处理它尝试在你的代码中执行这样的

 if (googleMap == null) { // Your code } else if(googleMap != null) { marker = googleMap.addMarker(new MarkerOptions().position(new LatLng(18.520897, 73.772396)).title("DSK Ranwara Road")); } 

看看你是否有确切的清单许可。 我没有在清单中包含下面的许可,而是给出了这个错误。

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 

请在清单文件中包含以下一些权限

 <!-- - THIS IS THE USER PERMISSION FOR GETTING LATITUDE AND LONGTITUDE FROM INTERNET --> <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> 

当我有一个观点的时候,我把它放在我的片段中:

 @Override public void onPause() { Fragment fragment = (getChildFragmentManager().findFragmentById(R.id.fragment_map_map)); FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction(); ft.remove(fragment); ft.commit(); super.onPause(); } 

为了使Google API v2正常工作(我也在使用SupportMapFragment),您必须包含这些权限

  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-feature android:glEsVersion="0x00020000" android:required="true"/> 

我希望这会帮助你们。

PS我用这些权限在我的应用程序中添加一个简单的地图。 还有一些其他的权限, 这个链接也建议。

我得到了同样的错误信息:

原因很简单:重新创建一个视图

 public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ super.onCreateView(inflater,container,savedInstanceState); self_view=inflater.inflate(R.layout.fragment_player,container,false); return self_view; } 

onCreateView可能会被多次调用。

当发生这种情况时,上面的代码为这个片段创建一个新的视图,而旧的视图仍然在这个视图中。

这个错误会弹出一些适配器,不会与另一个适配器; 在我的情况下,FragmentStatePagerAdapter很高兴,FragmentPagerAdapter是杀人的,因为前者破坏了它的碎片,后者重用了它们。

如何解决我的问题后,搜索很多,把这些行片段onPause方法。

 @Override public void onPause() { super.onPause(); final FragmentManager fragManager = this.getChildFragmentManager(); final Fragment fragment = fragManager.findFragmentById(R.id.map); if(fragment!=null){ fragManager.beginTransaction().remove(fragment).commit(); googleMap=null; } } 

这是强制空谷歌地图。 没有必要使用MapView,你可以不使用MapView