web-dev-qa-db-fra.com

Android - Android.view.InflateException: ligne de fichier XML binaire n ° 8: erreur lors de l'inflation d'un fragment de classe

Je développe une application à l’aide d’une variable NavigationDrawer, c’est-à-dire DrawerLayout, et je navigue vers différents Fragments. Lorsque j'appelle un Map_Fragment_Page, l'application se bloque, mais pas la première fois. Pour la première fois, il affiche correctement la variable Map, mais après cela, lorsque je navigue dans différents fragments et que je reviens à Map_Fragment_Page, il se bloque et génère une erreur Android.view.InflateException: Binary XML file line #8: Error inflating class fragment.

J'ai essayé tellement de solutions différentes et j'ai également effectué une recherche sur Google mais je n'ai toujours pas obtenu la solution requise. Le problème n'est pas encore résolu.

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;

    }
}
48
Mitesh Shah
Yes.. I want Map inside a Fragment.

Vous devriez utiliser 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

<?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>

Mettre à jour:

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

getMap() est obsolète. Utilisez getMapAsync(OnMapReadyCallback) à la place. La méthode de rappel vous fournit une instance de GoogleMap garantie comme étant non nulle et prête à être utilisée.

62
Raghunandan

Donc, si cela se bloque après avoir ouvert le fragment une seconde fois ... Tout ce dont vous avez besoin est dans OnDestroy

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

Apportez les modifications nécessaires si vous utilisez fragment de support.

10
Xjasz

Mes expériences faites avec des fragments ajoutés par xml-tag 

<fragment>...</fragment>.

Ces fragments sont normalement imbriqués et ne sont pas détruits lorsque le fragment parent est détruit. Une fois que vous essayez de les gonfler à nouveau, vous obtenez une exception qui se plaint fondamentalement d'avoir ce fragment déjà gonflé .. C'est pourquoi je détruis mes fragments imbriqués manuellement lorsque le fragment parent est détruit. Utilisez simplement les éléments suivants et ajustez-les à vos besoins. Ce code réside dans le fragment parent qui contient le fragment imbriqué en tant que balise xml.

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

Avec les fragments créés dynamiquement, il n’ya aucun problème. Dynamiquement signifie: vous n'avez pas utilisé fragment-xml-tag

J'espère que cela t'aides! Bonne programmation!

8
Alessandro Giusa

Je mets ça dans mon fragment 

@Override
public void onPause() {
    super.onPause();

    getChildFragmentManager().beginTransaction()
            .remove(mMapFragment)
            .commit();
}

Cela fonctionne sans remplacer à la MapView.

4
Sergey Nikitin

Change ça 

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

à

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

Dans votre classe


    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>
1
Ravv

Vérifiez que vous ayez ou non l'autorisation exacte du manifeste. Je n'avais pas inclus l'autorisation ci-dessous dans le manifeste, et c'était donner cette erreur.

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

Veuillez inclure certaines des autorisations suivantes dans votre fichier manifeste

<!-- - 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"/>
0
Pir Fahim Shah

J'ai reçu le même message d'erreur: 

La cause pour moi était simple: recréer une vue

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 peut être appelé plus d'une fois.

Lorsque cela se produit, le code ci-dessus crée une nouvelle vue pour le fragment alors que l'ancienne est toujours là.

L'erreur apparaît avec un adaptateur et pas avec un autre; dans mon cas, FragmentStatePagerAdapter était heureux et FragmentPagerAdapter était meurtrier parce que le premier a détruit ses fragments et le dernier les a réutilisés.

0
TastyCatFood

Je mets ceci dans mon fragment quand j'ai 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();
}
0
Cabezas

Comment j'ai résolu mon problème après avoir beaucoup cherché, mettez ces lignes à l'intérieur de la méthode fragment 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;
    }
}

Il est obligatoire de null googlemap . Il n'est pas nécessaire d'utiliser MapView, vous pouvez le faire sans utiliser MapView

0
Naeem Ibrahim

Pour que Google API v2 fonctionne (j'utilise également SupportMapFragment), vous devez inclure ces autorisations.

    <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"/>

J'espère que cela va vous aider les gars.

P.S J'ai utilisé ces autorisations pour ajouter une carte simple dans mon application. Il existe certaines autres autorisations que ce lien suggère également.

0
Junaid

Lorsque vous dites que votre code fonctionne pour la première fois, je pense que lorsque vous appelez à nouveau votre carte, votre objet googlemap n'est pas null et vous ne l'avez pas traité correctement. Essayez d'implémenter comme ceci dans votre code.

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