Android-SupportMapFragment不会重新加载

时间:2017-12-30 05:25:37

标签: android google-maps dictionary android-fragments supportmapfragment

我在SupportMapFragment内使用fragment,第一次,地图显示,但第二次我去了那个片段,地图变白了,没有显示。 我尝试了多种解决方案,包括:删除之前的fragment,覆盖onDestroy()onPause(),但是徒劳无功。 一个简单的问题:我应该使用MapView代替SupportMapFragment吗? 任何帮助都会受到赞赏,因为我已经挣扎了好几天。

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment


    if (view != null) {
        ViewGroup parent = (ViewGroup) view.getParent();
        if (parent != null)
            parent.removeView(view);
    }
    try {
        view = inflater.inflate(R.layout.rider_fragment_home, container, false);
    } catch (InflateException e) {
    }
    return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle 
  savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);


    mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
    mapFragment.onCreate(savedInstanceState);
    mapFragment.getMapAsync(this);

setUpLocation();
}
 @Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;

    mMap.setIndoorEnabled(false);
    mMap.setTrafficEnabled(false);
    mMap.setBuildingsEnabled(false);
    mMap.getUiSettings().setZoomControlsEnabled(true);
}

private void displayLocation() {
    if (ActivityCompat.checkSelfPermission(getActivity().getBaseContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
            ActivityCompat.checkSelfPermission(getActivity().getBaseContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        return;
    }

    if (mGoogleApiClient != null) {
        Common.mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if ( Common.mLastLocation != null) {
            final double latitude =  Common.mLastLocation.getLatitude();
            final double longitude =  Common.mLastLocation.getLongitude();

            //update to database (TO_DO)
            if (mCurrent != null) {
                mCurrent.remove(); // remove actual marker
            }
            mCurrent = mMap.addMarker(new MarkerOptions()
                    .icon(BitmapDescriptorFactory.fromResource(R.drawable.driver_marker))
                    .position(new LatLng(latitude, longitude))
                    .title("You"));
            //move camera to the new position
            mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude, longitude), 7.0f));
        }

    }

}

private void startLocationUpdates() {
    //ACCESS_COARSE_LOCATION : approximate location
    //ACCESS_FINE_LOCATION : exact location
    if (ActivityCompat.checkSelfPermission(getActivity().getBaseContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
            ActivityCompat.checkSelfPermission(getActivity().getBaseContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        return;
    }
    if (mGoogleApiClient != null) {
        //requestLactionUpdates : register the current activity to be updated periodically
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    }

}

@Override
public void onConnected(@Nullable Bundle bundle) {
    displayLocation();
    startLocationUpdates();
}

@Override
public void onConnectionSuspended(int i) {
    mGoogleApiClient.connect();
}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}

@Override
public void onLocationChanged(Location location) {
    Common.mLastLocation = location;
    displayLocation();

    if (Common.mLastLocation != null) {
        new LocationService().LocationUser(getActivity(), Common.mLastLocation.getLatitude() + "", Common.mLastLocation.getLongitude() + "", LoginFragment.user.getUserID());

        //update last seen location
        String lat = String.valueOf(Common.mLastLocation.getLatitude());
        String lng = String.valueOf(Common.mLastLocation.getLongitude());

    }

}

@Override
public void onDetach() {
    super.onDetach();

    try {
        Field childFragmentManager = Fragment.class
                .getDeclaredField("mChildFragmentManager");
        childFragmentManager.setAccessible(true);
        childFragmentManager.set(this, null);

    } catch (NoSuchFieldException e) {
        throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
    }
}
@Override
public void onResume() {
    super.onResume();
    mapFragment.onResume();
}

@Override
public void onPause() {
    super.onPause();
    mapFragment.onPause();
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSION_REQUEST_CODE:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                if (checkPlayServices()) {
                    buildGoogleApiClient();
                    createLocationRequest();
                    displayLocation();
                }
            }
    }
}

private void setUpLocation() {

    if (ActivityCompat.checkSelfPermission(getActivity().getBaseContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
            ActivityCompat.checkSelfPermission(getActivity().getBaseContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

        ActivityCompat.requestPermissions(getActivity(), new String[]{
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION
        }, MY_PERMISSION_REQUEST_CODE);
    } else {
        if (checkPlayServices()) {
            buildGoogleApiClient();
            createLocationRequest();
            displayLocation();

        }
    }

}

private void createLocationRequest() {
    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(UPDATE_INTERVAL);
    mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}

private void buildGoogleApiClient() {
    mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
    mGoogleApiClient.connect();
}


private boolean checkPlayServices() {

    int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity().getApplicationContext());
    if (resultCode != ConnectionResult.SUCCESS) {


        if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
            //if their is an error and it's recoverable , an error dialog is shown to tell the user about error and direct them to playStore if Google Play services is out of date or missing
            GooglePlayServicesUtil.getErrorDialog(resultCode, getActivity(), PLAY_SERVICE_RES_REQUEST).show();
        } else {
            Toast.makeText(getActivity().getApplicationContext(), "This device is not supported", Toast.LENGTH_SHORT).show();
        }
        return false;
    }
    return true;
}

2 个答案:

答案 0 :(得分:0)

尝试使用Fragment.java

inflate if null

 @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

 if (view == null) 
 {
    view = inflater.inflate(R.layout.rider_fragment_home, container, false);
 }

    mapFragment = (SupportMapFragment) this.getChildFragmentManager().findFragmentById(R.id.map);
    mapFragment.onCreate(savedInstanceState);
    mapFragment.getMapAsync(this);

    setUpLocation();

    return view;
}

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

    mMap.setIndoorEnabled(false);
    mMap.setTrafficEnabled(false);
    mMap.setBuildingsEnabled(false);
    mMap.getUiSettings().setZoomControlsEnabled(true);
}

答案 1 :(得分:-1)

  <fragment
    android:id="@+id/maplocation"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />


public class LocationFragment extends Fragment implements GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener,
    LocationListener {

private SupportMapFragment mapFragment;
private GoogleMap map;
private GoogleApiClient mGoogleApiClient;
ArrayList markerPoints;
private LocationRequest mLocationRequest;
private long UPDATE_INTERVAL = 15000;  /* 15 secs */
private long FASTEST_INTERVAL = 5000; /* 5 secs */
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private AVLoadingIndicatorView progressBar;
private static View view;


public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    if (view != null) {
        ViewGroup parent = (ViewGroup) view.getParent();
        if (parent != null)
            parent.removeView(view);
    }
    try {
        view = inflater.inflate(R.layout.location_fragment, container, false);
    } catch (InflateException e) {

    }

    markerPoints = new ArrayList();
    mapFragment = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.maplocation));
    if (mapFragment != null) {
        mapFragment.getView().setClickable(false);
        mapFragment.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(GoogleMap map) {
                loadMap(map);
            }
        });
    } else {
        Toast.makeText(getActivity(), getResources().getString(R.string.Error_Map_Fragment_was_null), Toast.LENGTH_SHORT).show();
    }

    mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
            // The next two lines tell the new client that “this” current class will handle connection stuff
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            //fourth line adds the LocationServices API endpoint from GooglePlayServices
            .addApi(LocationServices.API)
            .build();

    // Create the LocationRequest object
    mLocationRequest = LocationRequest.create()
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
            .setInterval(1000 * 1000)        // 10 seconds, in milliseconds
            .setFastestInterval(1000 * 1000); // 1 second, in milliseconds

    // mGoogleApiClient.connect();

    setRetainInstance(true);

    return view;
}

protected void loadMap(GoogleMap googleMap) {
    map = googleMap;
    if (map != null) {
        // Map is ready
        Toast.makeText(getActivity(), getResources().getString(R.string.Map_Fragment_was_loaded_properly), Toast.LENGTH_SHORT).show();
        map.setMyLocationEnabled(true);

        map.setOnMapClickListener(new GoogleMap.OnMapClickListener() {

            @Override
            public void onMapClick(LatLng point) {
                //onMapTouch(point);
            }
        });


    } else {
        if(isAdded()){
            Toast.makeText(getActivity(), getResources().getString(R.string.Error_Map_was_nul), Toast.LENGTH_SHORT).show();
        }
    }
}

/*
 * Called when the Activity becomes visible.
*/
@Override
public void onStart() {
    super.onStart();
}

/*
 * Called when the Activity is no longer visible.
 */
@Override
public void onStop() {
    // Disconnecting the client invalidates it.
    if (mGoogleApiClient != null) {
        mGoogleApiClient.disconnect();
    }
    super.onStop();
}

/*
 * Handle results returned to the FragmentActivity by Google Play services
 */
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Decide what to do based on the original request code
    switch (requestCode) {

        case CONNECTION_FAILURE_RESOLUTION_REQUEST:
        /*
         * If the result code is Activity.RESULT_OK, try to connect again
         */
            switch (resultCode) {
                case Activity.RESULT_OK:
                    mGoogleApiClient.connect();
                    break;
            }

    }
}

// Fetches data from url passed
private boolean isGooglePlayServicesAvailable() {
    // Check that Google Play services is available
    int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity());
    // If Google Play services is available
    if (ConnectionResult.SUCCESS == resultCode) {
        // In debug mode, log the status
        Log.d("Location Updates", "Google Play services is available.");
        return true;
    } else {
        // Get the error dialog from Google Play services
        Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(resultCode, getActivity(),
                CONNECTION_FAILURE_RESOLUTION_REQUEST);

        // If Google Play services can provide an error dialog
        if (errorDialog != null) {
            // Create a new DialogFragment for the error dialog
            ErrorDialogFragment errorFragment = new ErrorDialogFragment();
            errorFragment.setDialog(errorDialog);
            errorFragment.show(getFragmentManager(), "Location Updates");
        }

        return false;
    }
}


/*
 * Called by Location Services when the request to connect the client
 * finishes successfully. At this point, you can request the current
 * location or start periodic updates
 */
@Override
public void onConnected(Bundle dataBundle) {
    // Display the connection status
    Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
    if (location != null) {
        if (isAdded()) {
            Toast.makeText(getActivity(), getResources().getString(R.string.GPS_location_was_found), Toast.LENGTH_SHORT).show();
        }
        LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
        CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 6);
        map.animateCamera(cameraUpdate);
        // Marker marker = map.addMarker(new MarkerOptions().position(latLng).app_icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_launcher)).flat(true).anchor(0.5f,0.5f));
        onMapTouch(latLng);
        LatLng latLng1 = new LatLng("your latitude", "your longitude");
        onMapTouch(latLng1);
        startLocationUpdates();
    } else {
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        if(isAdded()){
            Toast.makeText(getActivity(), getResources().getString(R.string.Current_location_was_nullenable_GPS_on_emulator), Toast.LENGTH_SHORT).show();
        }
    }
}

protected void startLocationUpdates() {
    mLocationRequest = new LocationRequest();
    mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
    mLocationRequest.setInterval(UPDATE_INTERVAL);
    mLocationRequest.setFastestInterval(FASTEST_INTERVAL);

    //LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, (LocationListener) getActivity());

    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
            mLocationRequest, this);

}


/*
 * Called by Location Services if the connection to the location client
 * drops because of an error.
 */
@Override
public void onConnectionSuspended(int i) {
    if (i == CAUSE_SERVICE_DISCONNECTED) {
        Toast.makeText(getActivity(), getResources().getString(R.string.Disconnected_Please_reconnect), Toast.LENGTH_SHORT).show();
    } else if (i == CAUSE_NETWORK_LOST) {
        Toast.makeText(getActivity(), getResources().getString(R.string.Network_lost_Please_reconnect), Toast.LENGTH_SHORT).show();
    }
}

/*
 * Called by Location Services if the attempt to Location Services fails.
 */
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    /*
     * Google Play services can resolve some errors it detects. If the error
     * has a resolution, try sending an Intent to start a Google Play
     * services activity that can resolve error.
     */
    if (connectionResult.hasResolution()) {
        try {
            // Start an Activity that tries to resolve the error
            connectionResult.startResolutionForResult(getActivity(),
                    CONNECTION_FAILURE_RESOLUTION_REQUEST);
            /*
             * Thrown if Google Play services canceled the original
             * PendingIntent
             */
        } catch (IntentSender.SendIntentException e) {
            // Log the error
            e.printStackTrace();
        }
    } else {
        if (isAdded()) {
            Toast.makeText(getActivity(), getResources().getString(R.string.Sorry_Location_services_not_available_t_oyou), Toast.LENGTH_LONG).show();
        }

    }
}

@Override
public void onLocationChanged(Location location) {
    LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
   /* if (marker == null) {
        marker.remove();
        marker = map.addMarker(new MarkerOptions().position(latLng).app_icon(BitmapDescriptorFactory.fromResource(R.drawable.vehicle_marker)));
    }

    marker.setPosition(latLng);*/
    CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 14);
    map.animateCamera(cameraUpdate);

    String msg = "Updated Location: " +
            Double.toString(location.getLatitude()) + "," +
            Double.toString(location.getLongitude());
    //  Toast.makeText(getActivity(), msg, Toast.LENGTH_SHORT).show();
}


// Define a DialogFragment that displays the error dialog
public static class ErrorDialogFragment extends DialogFragment {

    // Global field to contain the error dialog
    private Dialog mDialog;

    // Default constructor. Sets the dialog field to null
    public ErrorDialogFragment() {
        super();
        mDialog = null;
    }

    // Set the dialog to display
    public void setDialog(Dialog dialog) {
        mDialog = dialog;
    }

    // Return a Dialog to the DialogFragment.
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return mDialog;
    }
}

// Fetches data from url passed
private class DownloadTask extends AsyncTask<String, Void, String> {

    // Downloading data in non-ui thread
    @Override
    protected String doInBackground(String... url) {

        // For storing data from web service
        String data = "";

        try {
            // Fetching the data from web service
            data = downloadUrl(url[0]);
        } catch (Exception e) {
            Log.d("Background Task", e.toString());
        }
        return data;
    }

    // Executes in UI thread, after the execution of
    // doInBackground()
    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);

        ParserTask parserTask = new ParserTask();

        // Invokes the thread for parsing the JSON data
        parserTask.execute(result);

    }
}


/**
 * A class to parse the Google Places in JSON format
 */
private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String, String>>>> {

    // Parsing the data in non-ui thread
    @Override
    protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) {

        JSONObject jObject;
        List<List<HashMap<String, String>>> routes = null;

        try {
            jObject = new JSONObject(jsonData[0]);
            DirectionsJSONParser parser = new DirectionsJSONParser();

            // Starts parsing data
            routes = parser.parse(jObject);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return routes;
    }

    // Executes in UI thread, after the parsing process
    @Override
    protected void onPostExecute(List<List<HashMap<String, String>>> result) {
        ArrayList points = null;
        PolylineOptions lineOptions = null;
        MarkerOptions markerOptions = new MarkerOptions();

        // Traversing through all the routes
        for (int i = 0; i < result.size(); i++) {
            points = new ArrayList();
            lineOptions = new PolylineOptions();


            // Fetching i-th route
            List<HashMap<String, String>> path = result.get(i);

            // Fetching all the points in i-th route
            for (int j = 0; j < path.size(); j++) {
                HashMap<String, String> point = path.get(j);

                double lat = Double.parseDouble(point.get("lat"));
                double lng = Double.parseDouble(point.get("lng"));
                LatLng position = new LatLng(lat, lng);

                points.add(position);
            }

            // Adding all the points in the route to LineOptions
            lineOptions.addAll(points);
            lineOptions.width(12);
            lineOptions.color(Color.RED);
            lineOptions.geodesic(true);

        }

        // Drawing polyline in the Google Map for the i-th route
        map.addPolyline(lineOptions);
    }
}

private String getDirectionsUrl(LatLng origin, LatLng dest) {

    // Origin of route
    String str_origin = "origin=" + origin.latitude + "," + origin.longitude;

    // Destination of route
    String str_dest = "destination=" + dest.latitude + "," + dest.longitude;

    // Sensor enabled
    String sensor = "sensor=false";

    // Building the parameters to the web service
    String parameters = str_origin + "&" + str_dest + "&" + sensor;

    // Output format
    String output = "json";

    // Building the url to the web service
    String url = "https://maps.googleapis.com/maps/api/directions/" + output + "?" + parameters;

    return url;
}

/**
 * A method to download json data from url
 */
private String downloadUrl(String strUrl) throws IOException {
    String data = "";
    InputStream iStream = null;
    HttpURLConnection urlConnection = null;
    try {
        URL url = new URL(strUrl);

        // Creating an http connection to communicate with url
        urlConnection = (HttpURLConnection) url.openConnection();

        // Connecting to url
        urlConnection.connect();

        // Reading data from url
        iStream = urlConnection.getInputStream();

        BufferedReader br = new BufferedReader(new InputStreamReader(iStream));

        StringBuffer sb = new StringBuffer();

        String line = "";
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }

        data = sb.toString();

        br.close();

    } catch (Exception e) {
        Log.d("Excep downloading url", e.toString());
    } finally {
        iStream.close();
        urlConnection.disconnect();
    }
    return data;
}

private void onMapTouch(LatLng point) {
    // Already two locations
    if (markerPoints.size() > 1) {
        markerPoints.clear();
        map.clear();
    }

    // Adding new item to the ArrayList
    markerPoints.add(point);

    // Creating MarkerOptions
    MarkerOptions options = new MarkerOptions();

    // Setting the position of the marker
    options.position(point);

    /**
     * For the start location, the color of marker is GREEN and
     * for the end location, the color of marker is RED.
     */
    if (markerPoints.size() == 1) {
        options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
    } else if (markerPoints.size() == 2) {
        options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
    }

    // Add new marker to the Google Map Android API V2
    map.addMarker(options);

    // Checks, whether start and end locations are captured
    if (markerPoints.size() >= 2) {
        LatLng origin = (LatLng) markerPoints.get(0);
        LatLng dest = (LatLng) markerPoints.get(1);

        // Getting URL to the Google Directions API
        String url = getDirectionsUrl(origin, dest);

        DownloadTask downloadTask = new DownloadTask();

        // Start downloading json data from Google Directions API
        downloadTask.execute(url);
    }
}}