2015-06-22 7 views
20

Ich verwende com.google.android.gms:play-services-maps:7.5.0 Version der Google Maps-Dienste. Wenn ich versuche, das unten genannte zu rufen, bekomme ich java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.maps.SupportMapFragment.getMapAsync(com.google.android.gms.maps.OnMapReadyCallback)' on a null object reference.mapFragment.getMapAsync (this) - NullPointerException

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    SupportMapFragment mapFragment = (SupportMapFragment) getActivity().getSupportFragmentManager() 
      .findFragmentById(R.id.map); 
    mapFragment.getMapAsync(this); //error 

    return inflater.inflate(R.layout.fragment_example_map, container, false); 
} 

fragment_example_map.xml Datei:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context="app.ExampleMap"> 

    <fragment xmlns:android="http://schemas.android.com/apk/res/android" 
     android:name="com.google.android.gms.maps.SupportMapFragment" 
     android:id="@+id/map" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"/> 
</FrameLayout> 

Antwort

6

Sie versuchen, ein Fragment zu finden, bevor es existiert. Sie geben an, dass das Layout mit dem Fragment fragment_example_map.xml ist. Sie versuchen jedoch, das Kartenfragment zu finden, bevor Sie diese Layoutdatei aufblasen. Dies wird nicht funktionieren.

Darüber hinaus scheinen Sie zu versuchen, auf das Kartenfragment innerhalb eines anderen Fragments zuzugreifen, in der onCreateView() Methode dieses Fragments. Ich weiß nicht, warum Sie Fragmente hier verschachteln, da es Ihren Code komplexer und zerbrechlicher macht, ohne dass dies offensichtlich ist.

+0

Wo wäre ein geeigneter Ort sein, der 'getMapAsync()' dann anrufen? Grundsätzlich hat meine App 3 Fragmente, 1 Aktivität und einen ViewPager, um zwischen diesen Fragmenten zu gleiten. Sollte es die Aktivität onCreate() der Aktivität sein? – Neutrino

+0

@Neutrino: "Grundsätzlich hat meine App 3 Fragmente, 1 Aktivität und einen ViewPager, der zwischen diesen Fragmenten verschoben werden kann" - dafür brauchst du keine verschachtelten Fragmente. Ihre Aktivität hat einen 'ViewPager'. Ihr 'PagerAdapter' erzeugt drei Fragmente. Es ist keine Verschachtelung erforderlich. Lassen Sie den 'FragmentPagerAdapter' direkt eine neue Instanz von' SupportMapFragment' erstellen; Sie müssen ein Layout nicht aufblasen.Dieses Beispiel zeigt einen 'ViewPager' mit zehn Kartenfragmenten: https://github.com/commonsguy/cw-omnibus/tree/master/MapsV2/Pager – CommonsWare

+0

Sorry, ich bin irgendwie verloren. Meine 'ViewPagerAdapter's' getItem() 'überprüft die Position und ruft in diesem Fall' return new Example() 'auf - ich schätze, dass das Aufblasen des Layouts in diesem Fall erforderlich ist? Und dann bin ich mir nicht so sicher, wo ich meine Operationen machen soll: in Fragmenten Code, Aktivitätencode oder anderswo. – Neutrino

89

Mein Kommentar in Karten mit Fragmente, zuerst sollten Sie die Ansicht refrenece wie Sie etwas von ihm nennen, ist der Grund, warum ich meine Ansicht
View view = inflater.inflate(R.layout.activity_maps, null, false);

Zweiten Aufruf Kind Fragment Manager this.getChildFragmentManager() statt getActivity().getSupportFragmentManager()

erste aufblasen

Hier ist die vollständige Beispiel Karte

import android.os.Bundle; 
import android.support.annotation.Nullable; 
import android.support.v4.app.Fragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 

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; 

public class ClinicFragment extends Fragment implements OnMapReadyCallback { 

    private GoogleMap mMap; 

    public static ClinicFragment newInstance() { 
     ClinicFragment fragment = new ClinicFragment(); 
     return fragment; 
    } 

    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.activity_maps, null, false); 

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

     return view; 
    } 


    /** 
    * Manipulates the map once available. 
    * This callback is triggered when the map is ready to be used. 
    * This is where we can add markers or lines, add listeners or move the camera. In this case, 
    * we just add a marker near Sydney, Australia. 
    * If Google Play services is not installed on the device, the user will be prompted to install 
    * it inside the SupportMapFragment. This method will only be triggered once the user has 
    * installed Google Play services and returned to the app. 
    */ 
    @Override 
    public void onMapReady(GoogleMap googleMap) { 
     mMap = googleMap; 

     // Add a marker in Sydney and move the camera 
     LatLng sydney = new LatLng(-34, 151); 
     mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney")); 
     mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney)); 
    } 
} 

erforderlich anzuzeigen Erlaubnis

<permission 
    android:name="your.package.name.permission.MAPS_RECEIVE" 
    android:protectionLevel="signature" /> 
<uses-permission android:name="your.package.name.permission.MAPS_RECEIVE"/> 

<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" /> 
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 

Plus Merkmalselement-

<uses-feature 
    android:glEsVersion="0x00020000" 
    android:required="true"/> 

meisten Import Google Maps Schlüssel

<meta-data 
    android:name="com.google.android.maps.v2.API_KEY" 
    android:value="your_key_here" /> 

aktualisieren diese Meta-Daten hinzufügen, wenn Sie Error inflating class fragment

Gesicht
<meta-data 
     android:name="com.google.android.geo.API_KEY" 
     android:value="your_key_here" /> 

sommerliche für Mainfest

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="your.package.name" > 
// permission here 

<application 
     android:name=".Activities.MyApplication" 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 

    // feature element 
    // maps key 

    </application> 

</manifest> 

activity_maps.xml

<fragment xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:map="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/map" 
    android:name="com.google.android.gms.maps.SupportMapFragment" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context="com.imaadv.leaynik.ClinicFragment" /> 
+10

warum diese Antwort nicht die beste Antwort ist? Vielen Dank für diese Antwort. – partiz

+0

@Fawzy, ich sehe nicht den 'getChildFragmentManager' – Jeremiah

+1

nur diese Lösung hat für mich funktioniert. danke –

0

ersetzen dieser Code

<fragment 
    android:name="com.google.android.gms.maps.MapFragment" 
    android:id="@+id/map" 
    android:layout_width="fill_parent" 
    android:layout_height="400dp" /> 

und

if (googleMap == null) { 
     mapFrag = (MapFragment)getFragmentManager().findFragmentById(R.id.map); 
     mapFrag.getMapAsync(this); 
    }else{ 
     GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); 

    } 
+1

isGooglePlayServicesAvailable (this) ist veraltet –

11

Verwenden Sie getChildFragmentManager() anstelle von getActivity().getSupportFragmentManager() im Fragment.

wie:

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

Je nach Android-Version oder SDK Version 5 und höher Verwendung getChildFragmentManager() und darunter verwendet getFragmentManager().

+0

Haben Sie ein Dokument oder einen Link darüber? In meinem Fall gibt getChildFragmentManager() für alle Android-Versionen einen gültigen FragmentManager zurück. Aber getFragmentManager gibt null für Android 4 und niedriger zurück. –

+0

Können Sie bitte Dokumentation bereitstellen. Dies ist in etwa die Lösung für mein Problem, aber ich kann es nicht in Produktion bringen, bis ich mir dieser Versionsnummern sicher bin. Alles, was ich lese, bezieht sich auf API 17 und höher. –

1

verwenden Sie dies.

GoogleMap gooleMap; 

    ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMapAsync(new OnMapReadyCallback() { 
     @Override 
     public void onMapReady(GoogleMap map) { 
      googleMap = map; 
      } 
0

Just Call supportMapFragment.getMapAsync(this); in onResume in Ihrer Aktivität

7

Wenn Ihre android:name="com.google.android.gms.maps.MapFragment" in Ihrem Fragmente verwenden dann Ihren Code ändern mit:

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

Allerdings, wenn Ihre android:name="com.google.android.gms.maps.SupportMapFragment" in Ihrem Fragmente verwendet Verwenden Sie dann diesen Code:

SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); 
     mapFragment.getMapAsync(this); 
1

getFragmentManager() wird möglicherweise nicht funktionieren, wenn Sie Map Inside Fragment verwenden. Sie müssen getChildFragmentManager() verwenden.

SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.fragment_track_order_map_fragment); 
mapFragment.getMapAsync(this); 

und unten ist meine XML-Deklaration

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

auch müssen Sie OnMapReadyCallback in Ihrem Fragment implementiert.

0

Die einfache Antwort ist, wenn Sie diese Karte Fragment hinzufügen möchten

<fragment 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/map" 
    android:name="com.google.android.gms.maps.SupportMapFragment" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:layout="@layout/fragment_home" /> 

in Ihrem Fragment: wie dieses Layout

<android.support.constraint.ConstraintLayout 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     xmlns:app="http://schemas.android.com/apk/res-auto" 
     xmlns:tools="http://schemas.android.com/tools" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
tools:context="com.example.android.earthreport.fragments.HomeFragment" 
     tools:layout_editor_absoluteX="8dp" 
     tools:layout_editor_absoluteY="81dp"> 

    <fragment 
xmlns:android="http://schemas.android.com/apk/res/android" 
      xmlns:tools="http://schemas.android.com/tools" 
      android:id="@+id/map" 
      android:name="com.google.android.gms.maps.SupportMapFragment" 
      android:layout_width="0dp" 
      android:layout_height="0dp" 
      app:layout_constraintBottom_toBottomOf="@id/guideline4" 
      app:layout_constraintEnd_toEndOf="parent" 
      app:layout_constraintStart_toStartOf="parent" 
      app:layout_constraintTop_toTopOf="@id/guideline3" 
      tools:layout="@layout/fragment_home" /> 
     </android.support.constraint.ConstraintLayout> 

Dann müssen Sie diese Zeile nach dem hinzufügen das Fragment wie folgt aufblasen

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

     // Find a reference to the {@link ListView} in the layout 
     // Inflate the layout for this fragment 
     // To get the referance we don't have findviewbyId 
     // method in fragment so we use view 
     View view = inflater.inflate(R.layout.fragment_home, container, false); 


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

In deiner Aktivität: wie dieses Layout

<?xml version="1.0" encoding="utf-8"?> 
<android.support.constraint.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <fragment xmlns:android="http://schemas.android.com/apk/res/android" 
     xmlns:tools="http://schemas.android.com/tools" 
     android:id="@+id/map" 
     android:name="com.google.android.gms.maps.SupportMapFragment" 
     android:layout_width="0dp" 
     android:layout_height="0dp" 
     app:layout_constraintBottom_toBottomOf="parent" 
     app:layout_constraintEnd_toEndOf="parent" 
     app:layout_constraintStart_toStartOf="parent" 
     app:layout_constraintTop_toTopOf="parent" 
     tools:context="package com.example.android.map" /> 

</android.support.constraint.ConstraintLayout> 

dann haben Sie dieses Stück Code hinzuzufügen.

Korrigieren Sie mich, wenn ich falsch bin, aber fügen Sie immer Kartenfragment nach dem Aufblasen des Layouts oder der Inhaltsansicht hinzu.

1

arbeitet für mich:

SupportMapFragment mapFragment = (SupportMapFragment)getChildFragmentManager() 
      .findFragmentById(R.id.map); 
    mapFragment.getMapAsync(this); 
Verwandte Themen