実行時にMapFragment
を追加するアクティビティを実装しました。 MapFragment
xmlには静的なfragment
があり、実行時に追加を取得しようとしています。また、実行時にマップフラグメントを追加するLollipopにいくつかの問題があることがわかりました。親切にチェックしてください 問題が発生しました および 一時的な解決策
以下にコードを示しました。
fragment_map.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=".fragment.MapsFragment">
<fragment
Android:id="@+id/map"
Android:name="com.google.Android.gms.maps.SupportMapFragment"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
tools:context="appCreators.bloodfinder.activity.MapsActivity"/>
<include
Android:id="@+id/layout"
layout="@layout/template_custom_spinner"/>
</FrameLayout>
_
MapsFragment.Java
onMapReadyCallback
を実装します
_public class MapsFragment extends SupportMapFragment implements OnMapReadyCallback
_
onResume
コールバック
_@Override
public void onResume() {
super.onResume();
((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map)).getMapAsync(this);
}
_
これは常に私をnullに戻し、私も試しましたが、
_((SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.map)).getMapAsync(this);
_
これもNullPointerException
を返します
MapsActivity.Java
_getSupportFragmentManager().beginTransaction().add(R.id.fragmentContainer, MapsFragment.newInstance()).commit();
_
これをActivityコールバックのonCreate
メソッドに追加します。
なぜまだNullPointerException
を取得しているのか理解できません!
時々私はAttempt to invoke interface method 'void com.google.maps.api.Android.lib6.e.fl.o()' on a null object reference
を取得します
助けていただければ幸いです!
UPDATE:まだ修正されていません次のエラーが発生します。ログを調べましたが、なぜこれが起こっているのかわかりません。
_Unable to resume activity {MapsActivity}: Java.lang.NullPointerException: Attempt to invoke interface method 'void com.google.maps.api.Android.lib6.e.fl.o()' on a null object reference
_
SOで与えられた答えを観察することによって、私はついにこの問題を自分で解決しました。私は自分のコードと回答のコードを比較しました。このAPIについては混乱があり、Googleの実装は非常に広範であるように思われます。この例外が繰り返しスローされました:
Attempt to invoke interface method 'void com.google.maps.api.Android.lib6.e.fl.o()' on a null object reference
同じ例外が発生しているSOの質問で、これらの実装のいくつかの何が問題になっているのかまだわかりませんが、これは私にとってはうまくいき、他の誰かにとってもうまくいくかもしれません。
これらはあなたがチェックする必要があるものです:
これらの両方があることを確認してください(私はAPIキーのメタデータしか持っていませんでした)
<meta-data
Android:name="com.google.Android.geo.API_KEY"
Android:value="@string/google_maps_key" />
<meta-data
Android:name="com.google.Android.gms.version"
Android:value="@integer/google_play_services_version" />
このようなxmlにフラグメントがあり、クラス属性は次のように正しいです。
<fragment
Android:id="@+id/google_map_fragment"
class="com.google.Android.gms.maps.SupportMapFragment"
Android:layout_width="match_parent"
Android:layout_height="match_parent"/>
私の場合、マップフラグメントは別のフラグメント内の子です。
この親フラグメントは明らかにMapFragmentまたはSupportMapFragmentであってはなりません。SupportMapFragmentからFragmentに変更した後、マップは完全に正常に表示されました。
public class ParentFragment extends Fragment {
他のすべては以前のままにしましたが、onCreateViewでマップを取得する代わりに、次のようにonViewCreatedで取得しました。
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.rewards_google_map_area);
if (mapFragment != null) {
LocationManager locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
if (locationManager != null && mapFragment.getMap() != null) {
googleMap=mapFragment.getMap();
//after this you do whatever you want with the map
}
}
}
私は他に何も変更せず、rootViewまたはparentViewをいじりませんでした。 @KonstantinLoginovからの回答にあるように
それを試して、私に知らせてください。
私の場合、フラグメントのxmlでraw MapView
を静的に使用します。問題は、mMapView.onCreate(...)
mMapView
がまだ膨張していないため、コール転送onViewCreated(...)
をonCreate()
に移動する必要があることでした。 MapView
を使用しない場合は、getMap()
を呼び出す瞬間を再確認する必要があります。内部のMapViewが膨らんだ後でなければなりません。
私はしばらく前に同様の問題に苦しんでいます。重要なのは、適切なタイミングで、Fragment
のgetMap()
でonViewCreated()
を実行することでした。
_public class LocationFragment extends Fragment {
private SupportMapFragment locationMap;
private View rootView;
protected View getFragmentView() {
View view = getView();
if (view == null) {
view = rootView;
}
return view;
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = getFragmentView();
if (rootView != null) {
ViewGroup parent = (ViewGroup) rootView.getParent();
if (parent != null) {
parent.removeView(rootView);
}
}
try {
rootView = inflater.inflate(R.layout.fragment_signup_specify_location, container, false);
} catch (InflateException ex) {
Log.e(LOG_TAG, "Inflate Exception in onCreateView; Caused by map fragment", ex);
}
......
return getFragmentView();
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
locationMap = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.locationMap);
if (locationMap != null) {
LocationManager locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
if (locationManager != null && locationMap.getMap() != null) {
locationMap.getMap().setMyLocationEnabled(true);
}
}
}
}
_
そして、そのXMLはあなたのもののように見えます:
_<FrameLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<fragment
Android:id="@+id/locationMap"
Android:layout_above="@+id/locationLabelTextView"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:name="com.google.Android.gms.maps.SupportMapFragment" />
</FrameLayout>
_
次に、onViewCreated()
でActivity
に、マップフラグメントを使用する準備ができたことを通知できます。
私はそれが役立つことを願っています
更新2019
それでもこの問題が発生する場合は、これを試してください:
SupportMapFrangemtを拡張しないでください!
public class MyFragment extends Fragment {
private SupportMapFragment fragment;
private GoogleMap map;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.layout_with_map, container, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
FragmentManager fm = getChildFragmentManager();
fragment = (SupportMapFragment) fm.findFragmentById(R.id.map_container);
if (fragment == null) {
fragment = SupportMapFragment.newInstance();
fm.beginTransaction().replace(R.id.map_container, fragment).commit();
}
}
}
MapViewを使用する場合は、mapView.onCreate()
の前にmapView.getMapAsync()
を呼び出したことを確認してください。フラグメントを使用していて、ビューがまだ初期化されていない場合は、mapView.onCreate()
メソッドでonViewCreated()
を呼び出すこともできます。