2017-04-04 2 views
0

Ich habe einenSupportMapFragmentManagers getMapAsync() nicht auslösen onMapReady (GoogleMap Karte)

public abstract class MyMapFragment implements OnMapReadyCallback 
{ 
    // 
    public GoogleMap googleMap; 
    SupportMapFragment mapFragment; 

    @IdRes 
    public abstract int getSupportMapFragId(); 

    @Override 
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 
    super.onViewCreated(view, savedInstanceState); 

    // http://stackoverflow.com/a/36592000/5102206 
    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){ 
     // Do something for lollipop and above versions 
     mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(getSupportMapFragId()); 
    } else { 
     // do something for phones running an SDK before lollipop 
     mapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(getSupportMapFragId()); 
    } 
    mapFragment.getMapAsync(this); 

    } 

    //.. 

    @Override 
    public void onMapReady(GoogleMap map) { 
    this.googleMap = map; 
    } 
} 

Nach meinen Stützpunkte onViewCreated() genannt wird, aber onMapReady() wird nicht aufgerufen (Stützpunkt auf this.googleMap = map nicht ausgelöst)

Auf Android 5, 6 und 7 funktioniert es gut und ich kann die Karte sehen .. Auf Android 4.X (API 16 - API 19) Geräte startet meine App, aber dann scheint es dort einzufrieren ... Ich sehe einen weißen leeren Bildschirm.

Auf Android 4.X-Betriebssystemgeräten: 1. Mit getFragmentManager() ist das Objekt mapFragment nach der else-Bedingung null. 2. Mit getChildFragmentMenager() scheint das Mapfragment gültig und nicht null zu sein, aber onMapReady wurde nicht ausgelöst.

Was fehlt mir hier?

+0

Warum nicht extend 'SupportMapFragment' verwenden oder direkt verwenden? Android Jelly (d. H. API 16) und höher decken 95,2% der von Google Play unterstützten Geräte ab. –

+0

@JPVentura Ich tat das vorübergehend, aber das änderte nichts. Ich hatte das gleiche Ergebnis. –

+0

1. Warum schachtest du 'SupportMapFragment' in' MyMapFragment'? 2. Warum suchen Sie explizit nach einer API-Ebene, die niemand verwendet? –

Antwort

1

Es gab ein Problem mit einem blockierenden Thread von RxJava auf Haupt-Thread. Es war also kein Problem mit Google Maps.

0

Ich verstehe nicht ganz, warum Sie Fragmente verschachteln, besonders weil es performance issues verursachen kann.

Wenn Sie einen Blick auf Google Samples nehmen, die Google Maps Beispiele verwendet ein Activity und SupportMapFragment:

public class MapsActivityCurrentPlace extends AppCompatActivity 
      implements OnMapReadyCallback, ConnectionCallbacks, 
      OnConnectionFailedListener { 

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

     // 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, 
         (FrameLayout)findViewById(R.id.map), false); 

       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; 
      } 
     }); 

     // Turn on the My Location layer and the related control on the map. 
     updateLocationUI(); 

     // Get the current location of the device and set the position of the map. 
     getDeviceLocation(); 
    } 

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

     if (savedInstanceState != null) { 
      mLastKnownLocation = savedInstanceState.getParcelable(KEY_LOCATION); 
      mCameraPosition = savedInstanceState.getParcelable(KEY_CAMERA_POSITION); 
     } 

     setContentView(R.layout.activity_maps); 

     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(); 

     mGoogleApiClient.connect(); 
    } 

    @Override 
    public void onConnected(Bundle connectionHint) { 
     SupportMapFragment mapFragment = 
      (SupportMapFragment) getSupportFragmentManager() 
       .findFragmentById(R.id.map); 
     mapFragment.getMapAsync(this); 
    } 

    @Override 
    public void onConnectionFailed(@NonNull ConnectionResult result) { 
     Log.d(TAG, result.getErrorMessage()); 
    } 

    @Override 
    public void onConnectionSuspended(int cause) { 
     Log.d(TAG, "Play services connection suspended"); 
    } 

} 
0

Hinweis: Sie können kein Layout in ein Fragment aufzublasen, wenn das Layout ein enthält. Nested-Fragmente werden nur unterstützt, wenn ein Fragment dynamisch hinzugefügt

Wenn Sie eine Karte in einem Fragment aufblasen wollen, können Sie entweder tun es in xml oder tun es in Java-Code wie folgt aus:

@Override 
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 
    super.onViewCreated(view, savedInstanceState); 
    FragmentManager fm = getChildFragmentManager(); 
    SupportMapFragment mapFragment = (SupportMapFragment) fm.findFragmentByTag("mapFragment"); 
    if (mapFragment == null) { 
     mapFragment = new SupportMapFragment(); 
     FragmentTransaction ft = fm.beginTransaction(); 
     ft.add(R.id.mapFragmentContainer, mapFragment, "mapFragment"); 
     ft.commit(); 
     fm.executePendingTransactions(); 
    } 
    mapFragment.getMapAsync(callback); 
} 

und auch die einfachen Behälter

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/mapFragmentContainer" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 
</LinearLayout> 

auch brauchen Sie nicht den onMapReadyCallback in der Klassendefinition zu implementieren. Statt Rückruf Sie direkt dort einen neuen OnMapReadyCallback() erstellen:

MapView.getMapAsync(new OnMapReadyCallback() { 
     @Override 
     public void onMapReady(GoogleMap mMap) { 
      googleMap = mMap; 
       } 
      }); 

Sie müssen auch diese

MapView mMapView; 
private GoogleMap googleMap; 

Ich hoffe, das hilft irgendwie!

Verwandte Themen