So originally my app would crash when I pressed the back button to return to the SpudMapFragment. Then i added the onDestroy() in the fragment however now i have a new weird crash with the same error msg. Now it crashes if i go to another fragment, return to SpudMapFragment, go to another fragment, then return to SpudMapFragment. Pretty much if i return to SpudMapFragment on th 3rd time it will crash.
This next section is a tldr of what the app looks like When the app opens, the SpudMapFragment is shown right away, if you swipe open the navigation drawer then a list of items show up, only two of them have fragments, this would be the Maps and Buy options. Clicking on maps will reload the maps fragment.
The error message: android.view.InflateException: Binary XML file line #2: Binary XML file line #2: Error inflating class fragment
The error points to "return inflater.inflate(R.layout.maps_fragment, container, false);" in 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" />
Stacktrace/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
Ive seen other errors similar to this but i have tried changing everything and nothing has worked, right now im working on the fragment life cycle since i think it has to do with that but im still only 1 month old in android. Any help would be super awesome, thank you. Ill reply rapidly to any responses if there are any questions or if it worked or did not work or if i tried it already.
edit 1: added stacktrace/logcat