2012-12-11 15 views
22

SupportMapFragmentまたはMapFragmentは使用しないでください。私はそれにコードの束で自分の基本クラスを持っています。AndroidマップV2 MapViewのカスタムフラグメント(NPE)

ドキュメントには、誰かがMapViewを単独で使用した場合、対応するライフサイクルメソッド(onCreate()onResume()など)を呼び出す必要があることが明確に記載されています。

FragmentにおけるライフサイクルメソッドのほとんどはActivityに似ていますが、私は私のFragment交互に切り替えるとき、私は最終的にonDestroy()またはonResume()方法で難読化NPEを取得します。

提供されるすべてのサンプルはMapViewActivityを使用しますが、カスタムFragmentは使用しません。

既に誰かが行っていますか?あなた自身のFragmentクラスにMapViewのサンプルコードを提供できますか?

答えて

12

ViewPagerに埋め込まれたカスタムフラグメント自体にMapView(v2)を組み込むことに成功しました。私の場合、MapViewはFragmentレイアウトファイルに含まれています。私はマップビュー(onCreate()をフラグメントから呼び出すonCreateView())を呼び出し、MapsInitializer.initialize(context)を手作業で呼び出して、BitmapDescriptorFactory(マーカのビットマップを取得する)のNullPointerExceptionを回避する必要がありました。この最後のトリックは奇妙で、Mapシステムがこの呼び出しなしで正しく初期化されない理由はわかりません。ちょうど現在のバージョンのバグかもしれません...

私の場合、私は持っていません任意NullPointerExceptiononResume()またはonDestroy()です。

+0

ある公式ドキュメントからMapsInitializer.initialize(コンテキスト)に関するいくつかの詳細は以下のとおりです。 [BitmapDescriptorFactory](http://developer.android .com/reference/com/google/android/gms/maps/model/BitmapDescriptorFactory.html) [MapsInitializer](http://developer.android.com/reference/com/google/android/gms/maps/MapsInitializer。 html#initialize(android.content.Context)) – PoPy

+1

私は既にMapオブジェクトを持っていますが、何らかの理由で例外がスローされます。私はこの静的で醜い呼び出しを追加したときに作業を終了しました。 – dnkoutso

+0

@PoPy自分自身と同じ操作をしようとしています(viewPagerのmapViewを含む)が、mapViewの状態(マーカー、位置、ズームなど)を維持するにはどうしますか? 1ページ(地図付き)から3ページに行き、1ページに戻ると私の状態は失われます! –

34

私はPoPyの答えで少し苦労しましたが、結局私はそれを管理しました。ここで私が思いついたのはこれです。おそらく、これはまた、この問題に出くわす他の人に役立ちます。

public class MyMapFragment extends Fragment { 

    private MapView mMapView; 
    private GoogleMap mMap; 
    private Bundle mBundle; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View inflatedView = inflater.inflate(R.layout.map_fragment, container, false); 

     try { 
      MapsInitializer.initialize(getActivity()); 
     } catch (GooglePlayServicesNotAvailableException e) { 
      // TODO handle this situation 
     } 

     mMapView = (MapView) inflatedView.findViewById(R.id.map); 
     mMapView.onCreate(mBundle); 
     setUpMapIfNeeded(inflatedView); 

     return inflatedView; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     mBundle = savedInstanceState; 
    } 

    private void setUpMapIfNeeded(View inflatedView) { 
     if (mMap == null) { 
      mMap = ((MapView) inflatedView.findViewById(R.id.map)).getMap(); 
      if (mMap != null) { 
       setUpMap(); 
      } 
     } 
    } 

    private void setUpMap() { 
     mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker")); 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     mMapView.onResume(); 
    } 

    @Override 
    public void onPause() { 
     super.onPause(); 
     mMapView.onPause(); 
    } 

    @Override 
    public void onDestroy() { 
     mMapView.onDestroy(); 
     super.onDestroy(); 
    } 
} 

そしてここでは、対応するres/layout/map_fragment.xmlです:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" > 

    <com.google.android.gms.maps.MapView 
     android:id="@+id/map" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" /> 
</RelativeLayout> 

あなたはRelativeLayoutを省略し(とのxmlnsがあなたの新しいまでdeclartion移動することができますルート要素、この場合はcom.google.android.gms.maps.MapView)を作成します。

+1

あなたのソリューションをありがとう、それは私を助けた。しかし、これはビューページャで使用していますか?私はこのソリューションとビューページャに問題があるためです。私は地図の状態を保持する方法を知らない(詳細についてはPoPyの答えに関する私のコメントを参照)。私たちを手伝ってくれますか ? –

+0

非常に便利です、ありがとうJens;) – Hesam

+0

@jens thanxコードでは、ページャの最初のフラグメントで動作しますが、2番目のフラグメントにスワイプすると、MapViewに何も表示されません。 FYI、フラグメントトランザクションは親フラグメントの 'onCreateView'メソッドで行われます。 私が見つけた別の問題 - GoogleMapオブジェクトに 'setOnMapClickListener'を実装しましたが、すべてのクリックが適切に処理されないようです。それはすべてではなく、いくつかのクリックを取得します。ここで何が起こるかわからない。 – Khobaib

-2

別々MapView、次の二つのことを使用している間ここで極めて重要で

//at Activity 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     MapsInitializer.initialize(this); 
     mapView.onCreate(savedInstanceState); 
    } 
    //or at Fragment 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 

     MapsInitializer.initialize(getActivity()); 
     mapView.onCreate(mBundle); 
    } 
    //along with the following 
    @Override 
    protected void onResume() { 
     super.onResume(); 
     if (mapView != null) 
     mapView.onResume(); 
     } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     if (mapView != null) 
     mapView.onDestroy(); 
    } 

    @Override 
    public void onLowMemory() { 
     super.onLowMemory(); 
     if (mapView != null) 
     mapView.onLowMemory(); 
    } 
+0

@martyonair:どこで2回呼んだのですか?私はあなたがそれを使用している活動または断片で言った。それをうまく読んでから、ただdownvote – laaptu

+0

ああ、ごめんなさい... – martyglaubitz

+0

@laaptu 'mapView'はどこで初期化しましたか? –

関連する問題