webentwicklung-frage-antwort-db.com.de

Woher weiß ich, dass die Karte bei der Verwendung von SupportMapFragment verwendet werden kann?

In der onCreate-Methode verwende ich die SupportMapFragment, um eine Karte anzuzeigen.

    SupportMapFragment fragment = new SupportMapFragment();
    getSupportFragmentManager().beginTransaction()
            .add(Android.R.id.content, fragment).commit();

In Verbindung damit möchte ich einen Marker hinzufügen. Das Problem ist, wenn der Aufruf von getMap null ist. Wann kann ich es erneut versuchen? Gibt es eine Veranstaltung, für die ich mich anmelden kann, oder ist mein Ansatz an und für sich falsch?

    mMap = ((SupportMapFragment)(getSupportFragmentManager().findFragmentById(R.id.map))).getMap();
    if(mMap == null)
        //what do I do here?

Die Karte wird zwar auf dem Telefon angezeigt, aber ich habe scheinbar kein Glück, die Referenz zum Hinzufügen von Markierungen zu erhalten.

UPDATE:

Der Grund, warum ich die SupportMapFragment über den Konstruktor erstellt habe, ist, dass die typische setContentView abstürzte und nicht funktionierte. Dies brachte mich in die Notlage, wo ich meine Referenz in der onCreate-Methode nicht finden konnte, da ich zu diesem Zeitpunkt tatsächlich die SupportMapFragment erstellte. Bei der weiteren Untersuchung scheint es, dass meine setContentView-Frage ein Nebenprodukt war, weil nicht sowohl die Google-Play-Services-JAR UND das Modul/src als Teil des gesamten Projekts eingerichtet wurden. Nachdem ich beides gemacht habe, funktioniert setContentView jetzt und ich kann die Referenz wie gewohnt über getMap() beziehen.

lots.xml ...

<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:Android="http://schemas.Android.com/apk/res/Android"
          Android:id="@+id/map"
          Android:name="com.google.Android.gms.maps.SupportMapFragment"
          Android:layout_width="match_parent"
          Android:layout_height="match_parent" />

LotsActivity.Java ...

public class LotsActivity extends FragmentActivity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.lots);

        GoogleMap mMap;
        mMap = ((SupportMapFragment)(getSupportFragmentManager().findFragmentById(R.id.map))).getMap();
        if(mMap == null)
            //this should not occur now
    }
29
Aaron McIver

BEARBEITEN: getMap ist jetzt veraltet

Das Problem ist, wenn der Aufruf von getMap null ist. Wann kann ich es erneut versuchen?

Das hängt von der Art des Problems ab.

Wenn Sie die SupportMapFragment über das <fragment>-Element im Layout einrichten, können Sie getMap() erfolgreich in onCreate() aufrufen. Wenn Sie jedoch die SupportMapFragment über den Konstruktor erstellen, ist dies zu früh - die GoogleMap ist noch nicht vorhanden. Sie können SupportMapFragment erweitern und onActivityCreated() überschreiben, da getMap() dann fertig ist.

getMap() kann jedoch alsonull für ein größeres Problem zurückgeben, z. B. wenn Google Play Services nicht installiert wird. Sie müssen etwas wie GooglePlayServicesUtil.isGooglePlayServicesAvailable() verwenden, um diesen Zustand zu erkennen und sich damit zu befassen, wie Sie möchten.

35
CommonsWare

Am Ende habe ich die SupportMapFragment-Klasse erweitert und einen Callback verwendet. Der Code ist hier:

public class MySupportMapFragment extends SupportMapFragment {

public MapViewCreatedListener itsMapViewCreatedListener;

// Callback for results

public abstract static class MapViewCreatedListener {
    public abstract void onMapCreated();
}

@Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = super.onCreateView(inflater, container, savedInstanceState);
    // Notify the view has been created
    if( itsMapViewCreatedListener != null ) {
        itsMapViewCreatedListener.onMapCreated();
    }
    return view;
}
}

Ich hätte lieber eine Schnittstelle verwendet und die onAttach (activity) -Methode überschrieben, aber in meinem Fall wollte ich nicht, dass der Rückruf zu meiner MainActivity zurückkehrt. Ich wollte, dass es zu einer Instanz von Fragment zurückkehrt. (Die GoogleMap war im Wesentlichen ein Fragment innerhalb eines Fragments) Ich habe den Callback eingerichtet und die Karte damit programmgesteuert geladen. Ich möchte itsMapViewCreatedListener im Konstruktor von MySupportMapFragment gesetzt haben, es wird jedoch davon abgeraten, andere als parameterlose Konstruktoren zu verwenden.

itsMySupportMapFragment = new MySupportMapFragment();
MapViewCreatedListener mapViewCreatedListener = new MapViewCreatedListener() {
    @Override
    public void onMapCreated() {
        initPlacesGoogleMapCtrl();
    }
};
itsMySupportMapFragment.itsMapViewCreatedListener = mapViewCreatedListener;
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.mapFragmentContainer, itsMySupportMapFragment);
transaction.addToBackStack(null);
transaction.commit();

Und dann, als ich zurückgerufen wurde, konnte ich die Karte bekommen; nicht mehr null!

public void initPlacesGoogleMapCtrl() {
    // Map ready, get it.
    GoogleMap googleMap = itsMySupportMapFragment.getMap();
    // Do what you want...
}
14
strangeluck

Ich würde die Antwort von CommonsWare kommentieren, aber ich habe nicht genug Vertreter dafür. Jedenfalls hatte ich auch das Problem, dass getMap () in onActivityCreated Null zurückgeben würde. Mein Setup ist folgendes: Ich habe MainActivity, die ein Fragment enthält. In der onCreateView-Methode dieses Fragments habe ich das SupportMapFragment erstellt und dann über den childFragmentManager dem Fragment hinzugefügt. Ich habe immer wieder auf SupportMapFragment Bezug genommen und erwartet, dass mir die Karte in onActivityCreated angezeigt wird, was aber nicht der Fall ist. Die Lösung für dieses Problem bestand darin, onActivityCreated des SupportMapFragment außer Kraft zu setzen, nicht jedoch das übergeordnete Fragment. Ich habe es in onCreateView so gemacht:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_location, container, false);
    mMapFragment = new SupportMapFragment() {
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            mMap = mMapFragment.getMap();
            if (mMap != null) {
                setupMap();
            }
        }
    };
    getChildFragmentManager().beginTransaction().add(R.id.framelayout_location_container, mMapFragment).commit();
return v;   
}
11
hordurh

Im vergangenen Monat (Dezember 2014) hat Google dieses Problem offiziell gelöst. In neueste (6.5) Google Play-Dienste :

Die getMap () -Methode in MapView und MapFragment ist jetzt zugunsten der neuen getMapAsync () -Methode veraltet.

Mit getMapAsync(OnMapReadyCallback callback) können Sie einen Listener einrichten, wenn GoogleMap bereit ist. Es wird im Rückruf übergeben und wird als nicht-null angegeben.

Von Google bereitgestellter Beispielcode hierfür:

public class MainActivity extends FragmentActivity
    implements OnMapReadyCallback {
...
}

und beim Initialisieren des Fragments:

MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);

wenn die Karte fertig ist, wird Ihr Rückruf angerufen

@Override
public void onMapReady(GoogleMap map) {
    map.addMarker(new MarkerOptions()
        .position(new LatLng(0, 0))
        .title("Marker"));
}
7
michalbrz

Mit den neuesten GoogleServices können Sie MapFragment.getMapAsync . Verwenden. Direkt aus den Dokumenten

Legt ein Callback-Objekt fest, das ausgelöst wird, wenn die GoogleMap-Instanz zur Verwendung bereit ist.

0
Mojo Risin

wenn map == null ist, finden Sie die Map

 if (mGoogleMap == null)
    {
        SupportMapFragment mapFragment1 = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);

        mapFragment1.getMapAsync(this);
    }

und rufen Sie dann Ihre Funktion onMapReady () auf;

0
Mahesh Gawhane

Sie können auch MapsInitializer.initialize(context); verwenden, wenn das Problem mit den nicht initialisierten Bibliotheken zusammenhängt.

0
theelfismike