mapFragment.getMapAsync ( ceci) - NullPointerException
j'utilise la version com.google.android.gms:play-services-maps:7.5.0
des services Google Maps. En essayant d'appeler le dessous je reçois 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
.
@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.fichier xml:
<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>
13 réponses
vous tentez de trouver un fragment avant qu'il n'existe. Vous indiquez que la disposition qui contient le fragment est fragment_example_map.xml
. Cependant, vous essayez de trouver le fragment de carte avant de gonfler ce fichier de mise en page. Cela ne fonctionnera pas.
au-delà de cela, vous semblez essayer d'atteindre le fragment de carte à partir de l'intérieur d'un autre fragment, dans la méthode onCreateView()
de ce fragment. Je ne sais pas pourquoi vous imitez des fragments ici, comme il semble que cela fera votre code plus complexe et plus fragile sans intérêt évident.
mon commentaire dans les cartes avec fragment, d'abord vous devriez réfréner votre vue comme vous l'appellerez quelque chose d'elle , c'est pourquoi je gonfle ma vue d'abord
View view = inflater.inflate(R.layout.activity_maps, null, false);
Deuxième appel enfant fragment manager this.getChildFragmentManager()
au lieu de getActivity().getSupportFragmentManager()
Voici l'exemple complet pour voir la carte
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));
}
}
permission
<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 la fonctionnalité de l'élément
<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>
la plupart d'importation google maps clé
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="your_key_here" />
mise à Jour ajouter cette méta-données si vous faites face à Erreur de gonflage de classe fragment
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="your_key_here" />
estival pour 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" />
utiliser getChildFragmentManager()
au lieu de getActivity().getSupportFragmentManager()
dans le fragment.
comme:
SupportMapFragment mapFragment = (SupportMapFragment)getChildFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
si vous utilisez android:name="com.google.android.gms.maps.MapFragment"
dans votre fragment alors changez votre code avec:
MapFragment mapFragment1 = (MapFragment)getFragmentManager().findFragmentById(R.id.map);
mapFragment1.getMapAsync(this);
cependant si vous utilisez android:name="com.google.android.gms.maps.SupportMapFragment"
dans votre fragment, utilisez alors ce code:
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
ça marche pour moi:
SupportMapFragment mapFragment = (SupportMapFragment)getChildFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
en fonction de la version Android ou SDK version 5 et au-dessus utiliser getChildFragmentManager() et au-dessous de lui utilisé getFragmentManager().
utilisez ceci.
GoogleMap gooleMap;
((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(GoogleMap map) {
googleMap = map;
}
getFragmentManager() ne fonctionnera peut-être pas lorsque vous utilisez map inside fragment. Vous devez utiliser getChildFragmentManager () .
SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.fragment_track_order_map_fragment);
mapFragment.getMapAsync(this);
et voici ma déclaration xml
<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" />
vous devez aussi implémenter OnMapReadyCallback dans votre fragment .
la réponse simple est si vous voulez ajouter Fragment de Carte ce
<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" />
dans votre fragment: comme cette disposition
<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>
alors vous devez ajouter cette ligne après le gonflage du fragment comme ceci
@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);
.....
dans votre activité: comme cette mise en page
<?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>
alors vous devez ajouter ce morceau de code.
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map_activity);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
corrigez-moi si je me trompe, mais ajoutez toujours un fragment de carte après avoir gonflé la mise en page ou réglé la vue de contenu.
remplacer ce code
<fragment
android:name="com.google.android.gms.maps.MapFragment"
android:id="@+id/map"
android:layout_width="fill_parent"
android:layout_height="400dp" />
et
if (googleMap == null) {
mapFrag = (MapFragment)getFragmentManager().findFragmentById(R.id.map);
mapFrag.getMapAsync(this);
}else{
GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
}
il suffit D'appeler supportMapFragment.getMapAsync(this);
dans onResume
dans votre activité
j'utilisais SupportMapFragment et en XML j'ai défini MapFragment name attribut
android:name="com.google.android.gms.maps.MapFragment"
donc j'ai remplacé le code par SupportMapFragment et il a commencé à fonctionner très bien
android:name="com.google.android.gms.maps.SupportMapFragment"
fait face au même problème. Puisque vous utilisez le fragment de carte dans un Fragment, utilisez getChildFragmentManager() au lieu de getActivity().getfragmentmanager () ou getfragmentmanager ()