返回到地图片段

时间:2016-09-13 16:20:06

标签: java android google-maps android-fragments

因此,当我按下后退按钮返回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

0 个答案:

没有答案