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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20919048/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 03:41:21  来源:igfitidea点击:

Android - android.view.InflateException: Binary XML file line #8: Error inflating class fragment

androidandroid-fragments

提问by Mitesh Shah

I am developing an app using a NavigationDraweri.e. DrawerLayoutand navigating to different Fragments. When I call a Map_Fragment_Pagethe application crashes, but not the first time. For the first time it displays the Mapproperly but after that when I navigate different fragments and again come to Map_Fragment_Pagethen it crashes giving an error android.view.InflateException: Binary XML file line #8: Error inflating class fragment

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

I tried so many different solutions and I also also searched on Googlebut still not getting the required solution. The problem is not yet fixed.

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

howtoreach.xml

如何访问.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

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;

    }
}

回答by Raghunandan

Yes.. I want Map inside a Fragment.

You should use a MapView

你应该使用一个 MapView

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

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

片段2.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>

Update:

更新:

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

getMap()is deprecated. Use getMapAsync(OnMapReadyCallback)instead. The callback method provides you with a GoogleMap instance guaranteed to be non-null and ready to be used.

getMap()已弃用。使用getMapAsync(OnMapReadyCallback)来代替。回调方法为您提供了一个 GoogleMap 实例,保证非 null 并且可以使用。

回答by Xjasz

So if it crashes after opening the fragment second time. All you need is this in OnDestroy

因此,如果它在第二次打开片段后崩溃。您只需要在 OnDestroy 中即可

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

Make what changes you need if you're using support fragment

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

回答by Alessandro Giusa

My experiences made with fragments added by xml-tag

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

<fragment>...</fragment>.

Those fragments are normally nested and do not destroy when the parent fragment gets destroyed. Once you try to inflate them again, you get the exception which basically complains of having this fragment already inflated. Therefore I destroy my nested fragments manually once the parent fragment gets destroyed. Simply use the following snipped and adjust it to your needs. This code resides in the parent fragment which has the nested fragment as xml-tag.

这些片段通常是嵌套的,并且在父片段被销毁时不会销毁。一旦你尝试再次膨胀它们,你会得到一个异常,它基本上抱怨这个片段已经膨胀了。因此,一旦父片段被销毁,我就会手动销毁我的嵌套片段。只需使用以下剪辑并根据您的需要进行调整即可。此代码驻留在具有嵌套片段作为 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();
    }
}

With dynamically created fragments there are no problems at all. Dynamically means: You have no fragment-xml-tag used

动态创建的片段完全没有问题。动态意味着:您没有使用 fragment-xml-tag

Hope this helps! Good programming!

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

回答by Sergey Nikitin

I put this in my fragment

我把这个放在我的片段中

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

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

It working without replacing to the MapView.

它无需替换 MapView 即可工作。

回答by Piyush

Change this

改变这个

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

to

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

回答by Ravv

In Your Class

在你的课堂上



    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>

回答by Ravv

As you are telling first time your code is working so i think when you again call your map your googlemapobject is not nulland you have not handled it properly try to Implement like this in your code

正如您第一次告诉您的代码正在运行,所以我认为当您再次调用您的地图时,您的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"));
}

回答by Junaid

For Google API v2 to work (I am also using SupportMapFragment), you must include these permissions

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

I hope this will help you guys.

我希望这会帮助你们。

P.S I used these permissions for adding a simple map in my app. There are certain other permissions which this linksuggests as well.

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

回答by Pir Fahim Shah

Check out that whether you have the exact manifest permission. I had not included the below permission in manifest, and it were giving this error.

检查您是否具有确切的清单权限。我没有在清单中包含以下权限,它给出了这个错误。

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

Please include some of the following permission in your manifest file

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

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

回答by Cabezas

I put this in my fragment when I have a viewpager:

当我有一个 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();
}