使用Maps API v2以编程方式初始化MapFragment

时间:2012-12-05 22:03:56

标签: android google-maps android-fragments

我正在尝试将MapFragment添加到我当前的Fragment中。嵌套片段的使用仅限于FragmentTransactions,您不能在布局中使用xml标记。 此外,我希望在用户按下按钮时将其添加到主片段中。因此,当用户按下该按钮并将其添加到适当的位置时,我将使用getInstance()以编程方式创建MapFragment。它显示正确,到目前为止一直很好。

问题是在附加MapFragment之后我需要获得对GoogleMap 的引用以放置标记,但getMap()方法返回null(作为片段的{尚未调用{1}}。

我查看了演示示例代码,我发现他们使用的解决方案是在onCreateView()中初始化MapFragment,并在调用onCreate()后在onResume()中获取对GoogleMap的引用。

我需要在MapFragment初始化之后立即获取对GoogleMap的引用,因为我希望用户能够使用按钮显示或隐藏地图。我知道一个可能的解决方案是如上所述在开始时创建Map并仅设置它的可见性消失,但我希望默认情况下关闭地图,这样如果没有明确要求它就不会占用用户的带宽为了它。

我尝试使用onCreateView(),但也无效。我有点卡住了。有任何想法吗? 这是我到目前为止的测试代码:

MapsInitializer

由于

4 个答案:

答案 0 :(得分:53)

好的AnderWebs在Google+给了我一个答案,但他太懒了......呃忙着再写这里,所以这里是简短的版本: 扩展MapFragment类并覆盖onCreateView()方法。完成此方法后,我们可以获得对que GoogleMap对象的非空引用。

这是我特别的解决方案:

public class MiniMapFragment extends SupportMapFragment {
    private LatLng mPosFija;

    public MiniMapFragment() {
        super();
    }

    public static MiniMapFragment newInstance(LatLng posicion){
        MiniMapFragment frag = new MiniMapFragment();
        frag.mPosFija = posicion;
        return frag;
    }

    @Override
    public View onCreateView(LayoutInflater arg0, ViewGroup arg1, Bundle arg2) {
        View v = super.onCreateView(arg0, arg1, arg2);
        initMap();
        return v;
    }

    private void initMap(){
        UiSettings settings = getMap().getUiSettings();
        settings.setAllGesturesEnabled(false);
        settings.setMyLocationButtonEnabled(false);

        getMap().moveCamera(CameraUpdateFactory.newLatLngZoom(mPosFija,16));
        getMap().addMarker(new MarkerOptions().position(mPosFija).icon(BitmapDescriptorFactory.fromResource(R.drawable.marker)));
    }
}

现在在上一个Fragment类中我做了

mMapFragment = MiniMapFragment.newInstance(new LatLng(37.4005502611301, -5.98233461380005));

也许它还不完美,因为在显示地图时屏幕会闪烁。但不确定问题是否是因为这个或其他原因。

答案 1 :(得分:25)

谢谢,发现这非常有帮助。我发布了我稍微修改过的解决方案,因为在地图准备就绪时告诉父片段更清晰。此方法也适用于saveInstanceState / restoreInstanceState循环。

public class CustomMapFragment extends SupportMapFragment {

    private static final String LOG_TAG = "CustomMapFragment";

    public CustomMapFragment() {
        super();

    }

    public static CustomMapFragment newInstance() {
        CustomMapFragment fragment = new CustomMapFragment();
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater arg0, ViewGroup arg1, Bundle arg2) {
        View v = super.onCreateView(arg0, arg1, arg2);
        Fragment fragment = getParentFragment();
        if (fragment != null && fragment instanceof OnMapReadyListener) {
            ((OnMapReadyListener) fragment).onMapReady();
        }
        return v;
    }



    /**
     * Listener interface to tell when the map is ready
     */
    public static interface OnMapReadyListener {

        void onMapReady();
    }
}

用作嵌套片段: -

public class ParentFragment extends Fragment implements OnMapReadyListener {

    ...

    mMapFragment = CustomMapFragment.newInstance();
    getChildFragmentManager().beginTransaction().replace(R.id.mapContainer, mMapFragment).commit();

    @Override
    public void onMapReady() {
        mMap = mMapFragment.getMap();
    }
    ...
}

希望它有所帮助。

答案 2 :(得分:14)

这是我的解决方案,我从之前发布的代码中获取灵感并进行了清理。我还添加了带有和不带有GoogleMapOptions参数的静态方法。

public class GoogleMapFragment extends SupportMapFragment {

    private static final String SUPPORT_MAP_BUNDLE_KEY = "MapOptions";

    public static interface OnGoogleMapFragmentListener {
        void onMapReady(GoogleMap map);
    }

    public static GoogleMapFragment newInstance() {
        return new GoogleMapFragment();
    }

    public static GoogleMapFragment newInstance(GoogleMapOptions options) {
        Bundle arguments = new Bundle();
        arguments.putParcelable(SUPPORT_MAP_BUNDLE_KEY, options);

        GoogleMapFragment fragment = new GoogleMapFragment();
        fragment.setArguments(arguments);
        return fragment;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mCallback = (OnGoogleMapFragmentListener) getActivity();
        } catch (ClassCastException e) {
            throw new ClassCastException(getActivity().getClass().getName() + " must implement OnGoogleMapFragmentListener");
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = super.onCreateView(inflater, container, savedInstanceState);
        if (mCallback != null) {
            mCallback.onMapReady(getMap());
        }
        return view;
    }

    private OnGoogleMapFragmentListener mCallback;
}

使用模式如下:

public class MyMapActivity implements OnGoogleMapFragmentListener {

    ...

    @Override
    public void onMapReady(GoogleMap map) {
        mUIGoogleMap = map;

        ...

    }

    ...

    private GoogleMap mUIGoogleMap;
}

答案 3 :(得分:3)

无需通过使用以下代码直接执行此操作SupportMapFragment

FragmentManager fm = getSupportFragmentManager(); // getChildFragmentManager inside fragments.
CameraPosition cp = new CameraPosition.Builder()
                    .target(initialLatLng) // your initial co-ordinates here. like, LatLng initialLatLng
                    .zoom(zoom_level)
                    .build();
SupportMapFragment mapFragment = SupportMapFragment.newInstance(new GoogleMapOptions().camera(cp));
fm.beginTransaction().replace(R.id.rl_map, mapFragment).commit();

layout

添加这段代码
<RelativeLayout
       android:id="@+id/rl_map"
       android:layout_width="fill_parent"
       android:layout_height="fill_parent" />

这会直接在GoogleMap加载Location,即initialLatLng。