使用SupportMapFragment时,如何知道地图已准备就绪?

Aar*_*ver 29 android google-maps google-maps-android-api-2

onCreate方法中,我正在利用它SupportMapFragment来显示地图.

    SupportMapFragment fragment = new SupportMapFragment();
    getSupportFragmentManager().beginTransaction()
            .add(android.R.id.content, fragment).commit();
Run Code Online (Sandbox Code Playgroud)

与此相关,我想添加一个标记.问题是当调用getMap为null时,我什么时候可以再试一次?是否有我可以注册的事件或我的方法本身是错的?

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

事实上,地图显示在手机上,但我似乎没有运气获得添加标记的参考.

更新:

SupportMapFragment通过构造函数创建的原因是因为典型的setContentView崩溃并且无法正常工作.这让我处于困境,在那里我无法获得我在onCreate方法中的参考,因为我当时正在创建SupportMapFragment它.在进一步调查中,似乎我的setContentView问题是没有将Google-play-services jar和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" />
Run Code Online (Sandbox Code Playgroud)

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
    }
Run Code Online (Sandbox Code Playgroud)

Com*_*are 35

编辑:getMap现在已弃用

问题是当对getMap的调用为null时,我什么时候可以再试一次?

这取决于问题的性质.

如果在布局中设置SupportMapFragmentvia <fragment>元素,则可以getMap()成功调用onCreate().但是,如果你SupportMapFragment通过构造函数创建,那太快了 - GoogleMap它还不存在.你可以扩展SupportMapFragment和覆盖onActivityCreated(),就像getMap()那时一样.

但是,getMap()可以返回null更大的问题,例如未安装Google Play服务.您需要使用类似的方法GooglePlayServicesUtil.isGooglePlayServicesAvailable()来检测这种情况并按照您的意愿处理它.

  • 正如我已经说过 - 这种方法对我不起作用.`getMap()`总是在这里返回`null`,尽管事实地图是可见的.所以对于一个记录,对我有用的是扩展`SupportMapFragment`并使用它来代替.我在子类`onCreateView()`中设置了map.不知道真正的罪魁祸首是什么. (2认同)

str*_*uck 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;
}
}
Run Code Online (Sandbox Code Playgroud)

我宁愿使用接口并覆盖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();
Run Code Online (Sandbox Code Playgroud)

然后,当我接到电话时,我可以得到地图; 不再无效!

public void initPlacesGoogleMapCtrl() {
    // Map ready, get it.
    GoogleMap googleMap = itsMySupportMapFragment.getMap();
    // Do what you want...
}
Run Code Online (Sandbox Code Playgroud)


小智 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;   
}
Run Code Online (Sandbox Code Playgroud)


mic*_*brz 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 {
...
}
Run Code Online (Sandbox Code Playgroud)

并在初始化片段时:

MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
Run Code Online (Sandbox Code Playgroud)

当map准备就绪时,将调用callback

@Override
public void onMapReady(GoogleMap map) {
    map.addMarker(new MarkerOptions()
        .position(new LatLng(0, 0))
        .title("Marker"));
}
Run Code Online (Sandbox Code Playgroud)