Android – android.view.InflateException:二进制XML文件行#8:错误膨胀类的片段
我正在开发一个应用程序使用NavigationDrawer
即DrawerLayout
和导航到不同的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