30

このonCreate方法では、を利用しSupportMapFragmentて地図を表示しています。

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

これに伴い、マーカーを追加したいと思います。問題は、への呼び出しgetMapがnullの場合、いつ再試行できますか?登録できるイベントはありますか、それとも私のアプローチ自体が間違っていますか?

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

地図は実際には電話に表示されていますが、マーカーを追加するための参照を取得するのに運がないようです。

アップデート:

コンストラクターを介してviaを作成した理由SupportMapFragmentは、標準setContentViewがクラッシュして機能しなかったためです。onCreateこれにより、実際にその時点で作成していたため、メソッドで参照を取得できなかったという苦境に陥りましSupportMapFragmentた。さらに調査したところ、私のsetContentView問題は、プロジェクト全体の一部としてGoogle-play-servicesjarとmodule/srcの両方が設定されていないことの副産物であるようです。これらの両方を実行すると、現在は機能しており、期待どおりにsetContentView参照を取得できます。getMap()

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
    }
4

7 に答える 7

35

編集:getMap現在非推奨です

問題は、getMapの呼び出しがnullの場合、いつ再試行できますか?

それは問題の性質に依存します。

SupportMapFragmentレイアウトの要素を介して設定すると、で正常に<fragment>呼び出すことができます。ただし、コンストラクターを介してviaを作成する場合、それは時期尚早です。まだ存在していません。それまでに準備ができているように、を拡張およびオーバーライドできます。getMap()onCreate()SupportMapFragmentGoogleMapSupportMapFragmentonActivityCreated()getMap()

ただし、Google Play開発者サービスがインストールされていないなど、より大きな問題が発生するgetMap()可能性もあります。この状態を検出し、必要に応じて対処するには、nullのようなものを使用する必要があります。GooglePlayServicesUtil.isGooglePlayServicesAvailable()

于 2012-12-26T23:01:54.443 に答える
14

最終的にSupportMapFragmentクラスを拡張し、コールバックを使用しました。コードはここにあります:

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;
}
}

インターフェイスを使用してonAttach(activity)メソッドをオーバーライドしたいのですが、私の場合、コールバックをMainActivityに戻さないようにしました。Fragmentのインスタンスに戻したかったのです。(GoogleMapは基本的にフラグメント内のフラグメントでした)コールバックを設定し、これをプログラムでマップにロードしました。MySupportMapFragmentのコンストラクター内にitsMapViewCreatedListenerを設定したいのですが、パラメーターなしのコンストラクター以外のものを使用することはお勧めしません。

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();

そして、電話がかかってきたとき、地図を手に入れることができました。もうnullはありません!

public void initPlacesGoogleMapCtrl() {
    // Map ready, get it.
    GoogleMap googleMap = itsMySupportMapFragment.getMap();
    // Do what you want...
}
于 2013-03-08T21:15:39.263 に答える
11

CommonsWareの回答についてコメントしますが、そのための十分な担当者がいません。とにかく、getMap()がonActivityCreatedでnullを返すというこの問題もありました。私の設定は次のとおりです。フラグメントを含むMainActivityがあります。そのフラグメントのonCreateViewメソッドで、SupportMapFragmentを作成し、childFragmentManagerを介してフラグメントに追加しました。私はSupportMapFragmentへの参照を維持し、それがonActivityCreatedのマップを提供することを期待していましたが、そうではありませんでした。この問題の解決策は、 SupportMapFragmentのonActivityCreatedをオーバーライドすることでしたが、親フラグメントはオーバーライドしませんでした。私はonCreateViewでこのようにしました:

@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;   
}
于 2013-02-19T11:56:33.403 に答える
7

先月(2014年12月)、Googleはこの問題の公式な解決策を提供しました。最新(6.5)のGoogle Playサービス

MapViewおよびMapFragmentのgetMap()メソッドは廃止され、新しいgetMapAsync()メソッドが採用されました。

を使用getMapAsync(OnMapReadyCallback callback)すると、GoogleMapの準備ができたときにリスナーを設定できます。これはコールバックで渡され、nullではないように提供されます。

Googleはこのためのサンプルコードを提供しました:

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

フラグメントを初期化するとき:

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

マップの準備ができると、コールバックが呼び出されます

@Override
public void onMapReady(GoogleMap map) {
    map.addMarker(new MarkerOptions()
        .position(new LatLng(0, 0))
        .title("Marker"));
}
于 2015-01-03T01:12:57.060 に答える
0

MapsInitializer.initialize(context);問題がライブラリが初期化されていないことに関連している場合にも使用できます。

于 2013-01-02T22:38:39.183 に答える
0

最新のGoogleServicesでは、MapFragment.getMapAsyncを使用できます。ドキュメントから直接

GoogleMapインスタンスを使用する準備ができたときにトリガーされるコールバックオブジェクトを設定します。

于 2014-12-31T16:44:15.393 に答える
0

map == nullの場合、マップを見つけます

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

        mapFragment1.getMapAsync(this);
    }

次に、関数onMapReady();を呼び出します。

于 2016-09-30T12:56:57.797 に答える