0

Я пытаюсь реализовать фрагмент фрагмента поддержки внутри фрагмента в активности с вкладками.Как установить маркер в SupportMapFragment в вкладке Активность?

Я пытаюсь установить карту и установить маркеры на карте. Мне удалось установить карту, но не маркер. Я попытался найти ответ, но я не мог решить проблему самостоятельно. Мне бы очень хотелось помочь.

Карта фрагмент кода:

public class Map_frag extends SupportMapFragment implements OnMapReadyCallback, GoogleMap.OnMapClickListener { 

    private SharedPreferences sp; 
    private Context context; 
    private float myLat, myLng, locLat, locLnf; 
    public GoogleMap map; 
    private Marker marker; 
    // Empty constructor 
    public Map_frag() {} 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     // Inflate the layout for this fragment 
     View v = inflater.inflate(R.layout.map_fragment, container,false); 
     context = getContext(); 
     sp = PreferenceManager.getDefaultSharedPreferences(context); 

     return v; 
    } 
    @Override 
    public void onResume() { 
     super.onResume(); 
     setUpMapIfNeeded(); 

    } 

    private void setUpMapIfNeeded() { 

     if (map == null) { 
      getMapAsync(this); 
     } 
    } 

    @Override 
    public void onMapReady(GoogleMap map) { 

     this.map = map; 
     onLocChange(); 
    } 

    public void onLocChange(){ 
     if (map ==null) { 
      map.clear(); 
      if (marker !=null){ 
       marker.remove(); 
      } 
      myLat = Float.parseFloat(sp.getString("lat", "0")); 
      myLng = Float.parseFloat(sp.getString("lng", "0")); 
      LatLng latLng = new LatLng(myLat, myLng); 
      marker = map.addMarker(new MarkerOptions().position(latLng).title("myLoc")); 

      map.animateCamera(CameraUpdateFactory. 
      newLatLngZoom(latLng,15)); 

     } 
     return; 
    } 

    @Override 
    public void onMapClick(LatLng latLng) { 

    } 
} 

И XML:

<?xml version="1.0" encoding="utf-8"?> 
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     xmlns:tools="http://schemas.android.com/tools" 
     android:orientation="vertical" android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:background="#00d05b5b"> 

      <fragment android:layout_width="fill_parent" 
       android:layout_height="fill_parent" 
       android:name="com.google.android.gms.maps.SupportMapFragment" 
       android:id="@+id/fragment2" 
       android:layout_gravity="center_horizontal" 
       tools:layout="@layout/place_autocomplete_fragment"/> 
    </LinearLayout> 
+0

вы только пытаетесь установить маркеры, когда карта является нулевым –

+0

что 'onLocChange'? –

ответ

0

onLocChange что это? onLocationChanged - метод переопределения. Вы можете использовать его.

Примечание: вы создали свой собственный onLocChange метод и вы называете его onMapReady поэтому он получает только называется в первой времени. Тогда onLocChange не вызывается. но если вы использовали метод переопределения, он получает вызов каждый раз при изменении местоположения!

внутри этого

удалить вас первым, если блок охватывает весь код и работает только когда карта имеет нулевое значение, когда карта является нулем не существует точки добавления маркеров, держите его подальше .. или использовать его как показано ниже

if(map==null){ 
    //map null 
    } else { 
    // add code for markers 
    } 

Если вы используете выше блока, это должно идти с еще часть

if (currLocationMarker != null) { 
// you already have a marker so when location changes you remove it and add a new one thats why you need this 
       currLocationMarker.remove(); 
      } 

latLng = new LatLng(location.getLatitude(), location.getLongitude()); 
     MarkerOptions markerOptions = new MarkerOptions(); // just added to clear thingsyou you can add this where instance creates only once 
     markerOptions.position(latLng); 
     markerOptions.title("Current Position"); 
     markerOptions.icon(iconForVehicleMarker); 

     currLocationMarker = mGoogleMap.addMarker(markerOptions); 

нужен полный пример все, что нужно знать (additional)? Посмотрите, как onMapReadyonLocationChaged и соответствующие методы, используемые здесь

import android.content.pm.PackageManager; 
import android.location.Location; 
import android.os.Bundle; 
import android.support.annotation.NonNull; 
import android.support.v4.app.ActivityCompat; 
import android.support.v4.content.ContextCompat; 
import android.support.v7.app.AppCompatActivity; 
import android.util.Log; 
import android.view.View; 
import android.widget.TextView; 

import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.api.GoogleApiClient; 
import com.google.android.gms.common.api.PendingResult; 
import com.google.android.gms.common.api.ResultCallback; 
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.location.places.PlaceLikelihood; 
import com.google.android.gms.location.places.PlaceLikelihoodBuffer; 
import com.google.android.gms.location.places.Places; 
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.CameraPosition; 
import com.google.android.gms.maps.model.LatLng; 
import com.google.android.gms.maps.model.Marker; 
import com.google.android.gms.maps.model.MarkerOptions; 

/** 
* An activity that displays a map showing places around the device's current location. 
*/ 
public class MapsActivityCurrentPlaces extends AppCompatActivity implements 
     OnMapReadyCallback, 
     GoogleApiClient.ConnectionCallbacks, 
     GoogleApiClient.OnConnectionFailedListener, 
     LocationListener { 

    private static final String TAG = MapsActivityCurrentPlaces.class.getSimpleName(); 
    private GoogleMap mMap; 
    private CameraPosition mCameraPosition; 

    // The entry point to Google Play services, used by the Places API and Fused Location Provider. 
    private GoogleApiClient mGoogleApiClient; 
    // A request object to store parameters for requests to the FusedLocationProviderApi. 
    private LocationRequest mLocationRequest; 
    // The desired interval for location updates. Inexact. Updates may be more or less frequent. 
    private static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000; 
    // The fastest rate for active location updates. Exact. Updates will never be more frequent 
    // than this value. 
    private static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = 
      UPDATE_INTERVAL_IN_MILLISECONDS/2; 

    // A default location (Sydney, Australia) and default zoom to use when location permission is 
    // not granted. 
    private final LatLng mDefaultLocation = new LatLng(-33.8523341, 151.2106085); 
    private static final int DEFAULT_ZOOM = 15; 
    private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1; 
    private boolean mLocationPermissionGranted; 

    // The geographical location where the device is currently located. 
    private Location mCurrentLocation; 

    // Keys for storing activity state. 
    private static final String KEY_CAMERA_POSITION = "camera_position"; 
    private static final String KEY_LOCATION = "location"; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     // Retrieve location and camera position from saved instance state. 
     if (savedInstanceState != null) { 
      mCurrentLocation = savedInstanceState.getParcelable(KEY_LOCATION); 
      mCameraPosition = savedInstanceState.getParcelable(KEY_CAMERA_POSITION); 
     } 

     // Retrieve the content view that renders the map. 
     setContentView(R.layout.activity_maps); 
     // Build the Play services client for use by the Fused Location Provider and the Places API. 
     buildGoogleApiClient(); 
     mGoogleApiClient.connect(); 
    } 

    /** 
    * Get the device location and nearby places when the activity is restored after a pause. 
    */ 
    @Override 
    protected void onResume() { 
     super.onResume(); 
     if (mGoogleApiClient.isConnected()) { 
      getDeviceLocation(); 
     } 
     updateMarkers(); 
    } 

    /** 
    * Stop location updates when the activity is no longer in focus, to reduce battery consumption. 
    */ 
    @Override 
    protected void onPause() { 
     super.onPause(); 
     if (mGoogleApiClient.isConnected()) { 
      LocationServices.FusedLocationApi.removeLocationUpdates(
        mGoogleApiClient, this); 
     } 
    } 

    /** 
    * Saves the state of the map when the activity is paused. 
    */ 
    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
     if (mMap != null) { 
      outState.putParcelable(KEY_CAMERA_POSITION, mMap.getCameraPosition()); 
      outState.putParcelable(KEY_LOCATION, mCurrentLocation); 
      super.onSaveInstanceState(outState); 
     } 
    } 

    /** 
    * Gets the device's current location and builds the map 
    * when the Google Play services client is successfully connected. 
    */ 
    @Override 
    public void onConnected(Bundle connectionHint) { 
     getDeviceLocation(); 
     // Build the map. 
     SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() 
       .findFragmentById(R.id.map); 
     mapFragment.getMapAsync(this); 
    } 

    /** 
    * Handles failure to connect to the Google Play services client. 
    */ 
    @Override 
    public void onConnectionFailed(@NonNull ConnectionResult result) { 
     // Refer to the reference doc for ConnectionResult to see what error codes might 
     // be returned in onConnectionFailed. 
     Log.d(TAG, "Play services connection failed: ConnectionResult.getErrorCode() = " 
       + result.getErrorCode()); 
    } 

    /** 
    * Handles suspension of the connection to the Google Play services client. 
    */ 
    @Override 
    public void onConnectionSuspended(int cause) { 
     Log.d(TAG, "Play services connection suspended"); 
    } 

    /** 
    * Handles the callback when location changes. 
    */ 
    @Override 
    public void onLocationChanged(Location location) { 
     mCurrentLocation = location; 
     updateMarkers(); 
    } 

    /** 
    * Manipulates the map when it's available. 
    * This callback is triggered when the map is ready to be used. 
    */ 
    @Override 
    public void onMapReady(GoogleMap map) { 
     mMap = map; 

     // Turn on the My Location layer and the related control on the map. 
     updateLocationUI(); 
     // Add markers for nearby places. 
     updateMarkers(); 

     // Use a custom info window adapter to handle multiple lines of text in the 
     // info window contents. 
     mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() { 

      @Override 
      // Return null here, so that getInfoContents() is called next. 
      public View getInfoWindow(Marker arg0) { 
       return null; 
      } 

      @Override 
      public View getInfoContents(Marker marker) { 
       // Inflate the layouts for the info window, title and snippet. 
       View infoWindow = getLayoutInflater().inflate(R.layout.custom_info_contents, null); 

       TextView title = ((TextView) infoWindow.findViewById(R.id.title)); 
       title.setText(marker.getTitle()); 

       TextView snippet = ((TextView) infoWindow.findViewById(R.id.snippet)); 
       snippet.setText(marker.getSnippet()); 

       return infoWindow; 
      } 
     }); 
     /* 
     * Set the map's camera position to the current location of the device. 
     * If the previous state was saved, set the position to the saved state. 
     * If the current location is unknown, use a default position and zoom value. 
     */ 
     if (mCameraPosition != null) { 
      mMap.moveCamera(CameraUpdateFactory.newCameraPosition(mCameraPosition)); 
     } else if (mCurrentLocation != null) { 
      mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
        new LatLng(mCurrentLocation.getLatitude(), 
          mCurrentLocation.getLongitude()), DEFAULT_ZOOM)); 
     } else { 
      Log.d(TAG, "Current location is null. Using defaults."); 
      mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mDefaultLocation, DEFAULT_ZOOM)); 
      mMap.getUiSettings().setMyLocationButtonEnabled(false); 
     } 
    } 

    /** 
    * Builds a GoogleApiClient. 
    * Uses the addApi() method to request the Google Places API and the Fused Location Provider. 
    */ 
    private synchronized void buildGoogleApiClient() { 
     mGoogleApiClient = new GoogleApiClient.Builder(this) 
       .enableAutoManage(this /* FragmentActivity */, 
         this /* OnConnectionFailedListener */) 
       .addConnectionCallbacks(this) 
       .addApi(LocationServices.API) 
       .addApi(Places.GEO_DATA_API) 
       .addApi(Places.PLACE_DETECTION_API) 
       .build(); 
     createLocationRequest(); 
    } 

    /** 
    * Sets up the location request. 
    */ 
    private void createLocationRequest() { 
     mLocationRequest = new LocationRequest(); 

     /* 
     * Sets the desired interval for active location updates. This interval is 
     * inexact. You may not receive updates at all if no location sources are available, or 
     * you may receive them slower than requested. You may also receive updates faster than 
     * requested if other applications are requesting location at a faster interval. 
     */ 
     mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS); 

     /* 
     * Sets the fastest rate for active location updates. This interval is exact, and your 
     * application will never receive updates faster than this value. 
     */ 
     mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS); 

     mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
    } 

    /** 
    * Gets the current location of the device and starts the location update notifications. 
    */ 
    private void getDeviceLocation() { 
     /* 
     * Request location permission, so that we can get the location of the 
     * device. The result of the permission request is handled by a callback, 
     * onRequestPermissionsResult. 
     */ 
     if (ContextCompat.checkSelfPermission(this.getApplicationContext(), 
       android.Manifest.permission.ACCESS_FINE_LOCATION) 
       == PackageManager.PERMISSION_GRANTED) { 
      mLocationPermissionGranted = true; 
     } else { 
      ActivityCompat.requestPermissions(this, 
        new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 
        PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION); 
     } 
     /* 
     * Get the best and most recent location of the device, which may be null in rare 
     * cases when a location is not available. 
     * Also request regular updates about the device location. 
     */ 
     if (mLocationPermissionGranted) { 
      mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 
      LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, 
        mLocationRequest, this); 
     } 
    } 

    /** 
    * Handles the result of the request for location permissions. 
    */ 
    @Override 
    public void onRequestPermissionsResult(int requestCode, 
              @NonNull String permissions[], 
              @NonNull int[] grantResults) { 
     mLocationPermissionGranted = false; 
     switch (requestCode) { 
      case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: { 
       // If request is cancelled, the result arrays are empty. 
       if (grantResults.length > 0 
         && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
        mLocationPermissionGranted = true; 
       } 
      } 
     } 
     updateLocationUI(); 
    } 

    /** 
    * Adds markers for places nearby the device and turns the My Location feature on or off, 
    * provided location permission has been granted. 
    */ 
    private void updateMarkers() { 
     if (mMap == null) { 
      return; 
     } 

     if (mLocationPermissionGranted) { 
      // Get the businesses and other points of interest located 
      // nearest to the device's current location. 
      @SuppressWarnings("MissingPermission") 
      PendingResult<PlaceLikelihoodBuffer> result = Places.PlaceDetectionApi 
        .getCurrentPlace(mGoogleApiClient, null); 
      result.setResultCallback(new ResultCallback<PlaceLikelihoodBuffer>() { 
       @Override 
       public void onResult(@NonNull PlaceLikelihoodBuffer likelyPlaces) { 
        for (PlaceLikelihood placeLikelihood : likelyPlaces) { 
         // Add a marker for each place near the device's current location, with an 
         // info window showing place information. 
         String attributions = (String) placeLikelihood.getPlace().getAttributions(); 
         String snippet = (String) placeLikelihood.getPlace().getAddress(); 
         if (attributions != null) { 
          snippet = snippet + "\n" + attributions; 
         } 

         mMap.addMarker(new MarkerOptions() 
           .position(placeLikelihood.getPlace().getLatLng()) 
           .title((String) placeLikelihood.getPlace().getName()) 
           .snippet(snippet)); 
        } 
        // Release the place likelihood buffer. 
        likelyPlaces.release(); 
       } 
      }); 
     } else { 
      mMap.addMarker(new MarkerOptions() 
        .position(mDefaultLocation) 
        .title(getString(R.string.default_info_title)) 
        .snippet(getString(R.string.default_info_snippet))); 
     } 
    } 

    /** 
    * Updates the map's UI settings based on whether the user has granted location permission. 
    */ 
    @SuppressWarnings("MissingPermission") 
    private void updateLocationUI() { 
     if (mMap == null) { 
      return; 
     } 

     if (mLocationPermissionGranted) { 
      mMap.setMyLocationEnabled(true); 
      mMap.getUiSettings().setMyLocationButtonEnabled(true); 
     } else { 
      mMap.setMyLocationEnabled(false); 
      mMap.getUiSettings().setMyLocationButtonEnabled(false); 
      mCurrentLocation = null; 
     } 
    } 
}