因此,当我按下后退按钮返回SpudMapFragment时,我的应用程序最初会崩溃。然后我在片段中添加了onDestroy()但是现在我有一个新的怪异崩溃与相同的错误消息。现在它崩溃了,如果我去另一个片段,返回SpudMapFragment,转到另一个片段,然后返回到SpudMapFragment。几乎如果我第三次回到SpudMapFragment就会崩溃。
下一部分是应用程序的样子 当应用程序打开时,SpudMapFragment立即显示,如果您滑动打开导航抽屉,然后显示项目列表,其中只有两个有碎片,这将是地图和购买选项。单击地图将重新加载地图片段。
错误消息:android.view.InflateException:二进制XML文件行#2:二进制XML文件行#2:错误膨胀类片段
错误指向“return inflater.inflate(R.layout.maps_fragment,container,false);”在SpudMapFragment中。
MainActivity.java
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.NavigationView;
import android.support.design.widget.Snackbar;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
SpudMapFragment firstFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Add the new activity and attach it to this button", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
//Create MapFragment as init fragment that's shown
if (findViewById(R.id.frame_layout) != null) {
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
if (savedInstanceState != null) {
return;
}
// Create a new Fragment to be placed in the activity layout
firstFragment = new SpudMapFragment();
// Add the fragment to the 'fragment_container' FrameLayout
getSupportFragmentManager().beginTransaction()
.add(R.id.frame_layout, firstFragment).addToBackStack(null).commit();
}
}
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.maps_list_item) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.frame_layout, firstFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
} else if (id == R.id.buy_icon) {
FoodFragment buyFragment = new FoodFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.frame_layout, buyFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
} else if (id == R.id.sell_icon) {
//TODO: Bring to new selling page
} else if (id == R.id.settings_drawer_item) {
//TODO: Bring to settings page
//TODO: Figure out what settings are needed
} else if (id == R.id.account_info) {
//TODO: Bring to place to connect payment info and receiving info
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
}
SpudMapFragment.java
import android.annotation.TargetApi;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class SpudMapFragment extends Fragment
implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
SupportMapFragment map_Fragment;
private GoogleMap mMap;
//Tag for logging
private final String TAG = "MapsActivity";
//Initialize Google Api Client to communicate with play services
GoogleApiClient mGoogleApiClient;
//Initialize Location Request variable
LocationRequest mLocationRequest;
//Users current position based on Latitude and Longitude
static LatLng CurrentUserLocationLatLng = new LatLng(0, 0);
//Variable for most recent location
Location mLastLocation;
final int PERMISSION_REQUEST_ACCESS_FINE_LOCATION = 1;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
return inflater.inflate(R.layout.maps_fragment, container, false);
}
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);
SupportMapFragment map_Fragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
map_Fragment.getMapAsync(this);
//Creating the map fragment
initializeMap();
//Create the Google Api Client for location services and having callbacks link to MapsActivity
buildGoogleApiClient();
}
private void initializeMap() {
if (map_Fragment == null) {
map_Fragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
map_Fragment.getMapAsync(this);
}
}
private void buildGoogleApiClient(){
mGoogleApiClient = new GoogleApiClient.Builder(getContext())
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
@Override
public void onStart() {
super.onStart();
//Connect Google Client Api
mGoogleApiClient.connect();
}
@Override
public void onResume(){
super.onResume();
}
@Override
public void onPause() {
super.onPause();
getChildFragmentManager().beginTransaction().remove(map_Fragment).commit();
}
@Override
public void onStop() {
super.onStop();
//Disconnect Google Api Client if connected
if (mGoogleApiClient.isConnected()){
mGoogleApiClient.disconnect();
}
}
@Override
public void onDestroy() {
super.onDestroy();
getChildFragmentManager().beginTransaction().remove(map_Fragment).commit();
}
@Override
public void onMapReady(GoogleMap googleMap) {
//Receive the Google Map and assign it to mMap
mMap = googleMap;
}
@Override
public void onConnected(@Nullable Bundle bundle) {
if (ActivityCompat.checkSelfPermission(getContext(),
android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// Check if user has denied access before, if so then explain why we need the app
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
android.Manifest.permission.ACCESS_FINE_LOCATION)) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setMessage("To see local activity you have /n to allow us access to your location.");
builder.setTitle("Location Services");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
showPermissionRequest();
}
});
builder.show();
} else {
// No explanation needed, we can request the permission
showPermissionRequest();
}
}
else if (ActivityCompat.checkSelfPermission(getContext(),
android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
//Set up settings on Location Request
//Interval of 10 seconds with emphasis on accuracy
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(10000);
//Get the current location
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
//Get current location and add it to the map
mapAndLocationInitializer();
}
}
private void showPermissionRequest(){
//Show dialog requesting for fine location permission
// This calls method onRequestPermissionResult passing it PERMISSION_REQUEST_ACCESS_FINE_LOCATION
ActivityCompat.requestPermissions(getActivity(),
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSION_REQUEST_ACCESS_FINE_LOCATION);
}
private void mapAndLocationInitializer(){
//Get the LatLng from the current location
CurrentUserLocationLatLng = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
//Add marker for current location
mMap.addMarker(new MarkerOptions().position(CurrentUserLocationLatLng));
//Initialize camera to zoom to current location when first opened
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(CurrentUserLocationLatLng, 17f));
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_ACCESS_FINE_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Set up settings on Location Request
//Interval of 10 seconds with emphasis on accuracy
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(10000);
//Get the current location
//noinspection MissingPermission
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
//noinspection MissingPermission
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
//Get current location and add it to the map
mapAndLocationInitializer();
} else {
//TODO
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
@Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Connection Suspended");
}
@Override
public void onLocationChanged(Location location) {
//Clear the previous location for the user and add a new one
mMap.clear();
CurrentUserLocationLatLng = new LatLng(location.getLatitude(), location.getLongitude());
mMap.addMarker(new MarkerOptions().position(CurrentUserLocationLatLng));
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Log.i(TAG, "Connection Failed");
}
}
maps_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<fragment android:id="@+id/map"
class ="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.spudgmail.rethy.spud.MainActivity"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android" />
堆栈跟踪/ logcat的
09-13 15:44:42.415 6046-6046/com.spudgmail.rethy.spud E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.spudgmail.rethy.spud, PID: 6046
android.view.InflateException: Binary XML file line #2: Binary XML file line #2: Error inflating class fragment
at android.view.LayoutInflater.inflate(LayoutInflater.java:539)
at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
at com.spudgmail.rethy.spud.SpudMapFragment.onCreateView(SpudMapFragment.java:62)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2080)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1108)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1290)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:801)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1677)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:536)
at android.os.Handler.handleCallback(Handler.java:746)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
Caused by: android.view.InflateException: Binary XML file line #2: Error inflating class fragment
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:782)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
at com.spudgmail.rethy.spud.SpudMapFragment.onCreateView(SpudMapFragment.java:62)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2080)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1108)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1290)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:801)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1677)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:536)
at android.os.Handler.handleCallback(Handler.java:746)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
Caused by: java.lang.IllegalArgumentException: Binary XML file line #2: Duplicate id 0x7f0e00e8, tag null, or parent id 0x7f0e00d9 with another fragment for com.google.android.gms.maps.SupportMapFragment
at android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2422)
at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(LayoutInflaterCompatHC.java:44)
at android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:186)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:746)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
at com.spudgmail.rethy.spud.SpudMapFragment.onCreateView(SpudMapFragment.java:62)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2080)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1108)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1290)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:801)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1677)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:536)
at android.os.Handler.handleCallback(Handler.java:746)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
09-13 15:44:45.157 6046-6046/com.spudgmail.rethy.spud I/Process: Sending signal. PID: 6046 SIG: 9
我已经看到了类似的其他错误,但我已经尝试改变一切,没有任何工作,现在我正在处理片段生命周期,因为我认为它与此有关但但我仍然只有1个月大的机器人。任何帮助都会超级棒,谢谢。如果有任何问题,或者如果它有效或无效,或者我已经尝试过,我会迅速回复任何回复。
编辑1:添加了stacktrace / logcat