Android – android.view.InflateException: archivo XML binario línea # 8: error al inflar el fragmento de la clase

Estoy desarrollando una aplicación usando un NavigationDrawer es decir, DrawerLayout y navegando a diferentes Fragments . Cuando llamo a Map_Fragment_Page la aplicación falla, pero no la primera vez. Por primera vez, muestra el Map correctamente, pero luego, cuando Map_Fragment_Page por diferentes fragmentos y vuelvo a Map_Fragment_Page , falla al dar un error android.view.InflateException: Binary XML file line #8: Error inflating class fragment

Probé con tantas soluciones diferentes y también busqué en Google pero aún no obtuve la solución requerida. El problema aún no está solucionado.

howtoreach.xml

     

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. 

Deberías usar un 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

     

Actualizar:

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

getMap() está en desuso. Use getMapAsync(OnMapReadyCallback) lugar. El método de callback le proporciona una instancia de GoogleMap que garantiza que no es nula y está lista para ser utilizada.

Entonces, si se bloquea después de abrir el fragmento por segunda vez. Todo lo que necesitas es esto en OnDestroy

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

Haga los cambios que necesita si está utilizando un fragmento de soporte

Mis experiencias hechas con fragmentos añadidos por xml-tag

 .... 

Esos fragmentos normalmente están nesteds y no se destruyen cuando el fragmento principal se destruye. Una vez que intentas inflarlos de nuevo, obtienes la excepción que básicamente se queja de tener este fragmento ya inflado. Por lo tanto, destruyo mis fragmentos nesteds manualmente una vez que el fragmento principal se destruye. Simplemente use el siguiente recorte y ajústelo a sus necesidades. Este código reside en el fragmento principal que tiene el fragmento nested como 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(); } } 

Con fragmentos creados dinámicamente no hay ningún problema. Dinámicamente significa: No tiene una etiqueta fragment-xml-tag utilizada

¡Espero que esto ayude! Buena progtwigción!

Puse esto en mi fragmento

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

Funciona sin reemplazar a MapView.

Cambia esto

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

a

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

En tu clase


  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


     

Como dices la primera vez que tu código está funcionando, creo que cuando vuelvas a llamar a tu mapa, tu objeto googlemap no es null y no lo has manejado correctamente. Intenta implementarlo así en tu código.

 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")); } 

Verifique si tiene el permiso de manifiesto exacto. No había incluido el permiso debajo en manifiesto, y estaba dando este error.

  

Por favor incluya algunos de los siguientes permisos en su archivo de manifiesto

        

Puse esto en mi fragmento cuando tengo un viewpager:

 @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(); } 

Para que Google API v2 funcione (también estoy usando SupportMapFragment), debe incluir estos permisos

       

Espero que esto los ayude chicos.

PD. Usé estos permisos para agregar un mapa simple en mi aplicación. Existen otros permisos que este enlace también sugiere.

Recibí el mismo mensaje de error:

La causa para mí fue simple: volver a crear una vista

 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 se puede llamar más de una vez.

Cuando eso sucede, el código anterior crea una nueva vista para el fragmento mientras el anterior todavía está alrededor.

El error aparece con algún adaptador y no con otro; en mi caso, FragmentStatePagerAdapter estaba contento y FragmentPagerAdapter era asesino porque el primero destruía sus fragmentos y el último los reutilizaba.

Cómo solucioné mi problema después de buscar mucho, pongo estas líneas dentro del fragmento Método de Pausa.

 @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; } } 

Es obligatorio anular googlemap. No es necesario usar MapView, puede hacerlo sin usar MapView