1

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

Spud
  • 11
  • 2

0 Answers0