50

現在のフラグメントにMapFragmentを追加しようとしています。ネストされたフラグメントの使用はFragmentTransactionsに制限されており、レイアウトでxmlタグを使用することはできません。また、ユーザーがボタンを押したときにメインフラグメントに追加したいと思います。getInstance()そのため、ユーザーがそのボタンを押したときにプログラムでMapFragmentを作成し、適切な場所に追加しています。これまでのところ、正しく表示されています。

問題は、MapFragmentをアタッチした後GoogleMap 、マーカーを配置するための参照を取得する必要があることですが、getMap()メソッドはnullを返します(フラグメントonCreateView()はまだ呼び出されていないため)。

デモのサンプルコードを見て、彼らが使用している解決策は、でMapFragmentを初期化し、が呼び出された後onCreate()にGoogleMapへの参照を取得することであることがわかりました。onResume()onCreateView()

ユーザーがボタンで地図を表示または非表示にできるようにしたいので、MapFragmentの初期化の直後にGoogleMapへの参照を取得する必要があります。考えられる解決策は、上記のように最初にマップを作成し、可視性をなくすように設定することですが、明示的に要求されない場合はユーザーの帯域幅を使用しないように、デフォルトでマップをオフにします。それのための。

で試しましたがMapsInitializer、どちらも機能しません。私はちょっと立ち往生しています。何か案は?これまでの私のテストコードは次のとおりです。

public class ParadaInfoFragment extends BaseDBFragment {
// BaseDBFragment is just a SherlockFragment with custom utility methods.

private static final String MAP_FRAGMENT_TAG = "map";
private GoogleMap mMap;
private SupportMapFragment mMapFragment;
private TextView mToggleMapa;
private boolean isMapVisible = false;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_parada_info, container, false);
    mToggleMapa = (TextView) v.findViewById(R.id.parada_info_map_button);
    return v;
}

@Override
public void onStart() {
    super.onStart();
    mToggleMapa.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!isMapVisible) {
                openMap();
            } else {
                closeMap();
            }
            isMapVisible = !isMapVisible;
        }
    });
}

private void openMap() {
    // Creates initial configuration for the map
    GoogleMapOptions options = new GoogleMapOptions().camera(CameraPosition.fromLatLngZoom(new LatLng(37.4005502611301, -5.98233461380005), 16))
            .compassEnabled(false).mapType(GoogleMap.MAP_TYPE_NORMAL).rotateGesturesEnabled(false).scrollGesturesEnabled(false).tiltGesturesEnabled(false)
            .zoomControlsEnabled(false).zoomGesturesEnabled(false);

    // Modified from the sample code:
    // It isn't possible to set a fragment's id programmatically so we set a
    // tag instead and search for it using that.
    mMapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentByTag(MAP_FRAGMENT_TAG);

    // We only create a fragment if it doesn't already exist.
    if (mMapFragment == null) {
        // To programmatically add the map, we first create a
        // SupportMapFragment.
        mMapFragment = SupportMapFragment.newInstance(options);
        // Then we add it using a FragmentTransaction.
        FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction();
        fragmentTransaction.add(R.id.parada_info_map_container, mMapFragment, MAP_FRAGMENT_TAG);
        fragmentTransaction.commit();
    }
    // We can't be guaranteed that the map is available because Google Play
    // services might not be available.
    setUpMapIfNeeded(); //XXX Here, getMap() returns null so  the Marker can't be added
    // The map is shown with the previous options.
}

private void closeMap() {
    FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction();
    fragmentTransaction.remove(mMapFragment);
    fragmentTransaction.commit();
}

private void setUpMapIfNeeded() {
    // Do a null check to confirm that we have not already instantiated the
    // map.
    if (mMap == null) {
        // Try to obtain the map from the SupportMapFragment.
        mMap = mMapFragment.getMap();
        // Check if we were successful in obtaining the map.
        if (mMap != null) {
            mMap.addMarker(new MarkerOptions().position(new LatLng(37.4005502611301, -5.98233461380005)).title("Marker"));
        }
    }
}
}

ありがとう

4

4 に答える 4

53

良いAnderWebsは私にGoogle+で答えをくれましたが、彼はあまりにも怠惰です....ここで再びそれを書くのに忙しいので、ここに短いバージョンがあります:MapFragmentクラスを拡張してメソッドをオーバーライドしますonCreateView()GoogleMapこのメソッドが実行された後、queオブジェクトへのnull以外の参照を取得できます。

これは私の特定の解決策です:

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

今、前のフラグメントクラスで私はします

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

地図を表示すると画面が点滅するので、まだ完璧ではないかもしれません。しかし、問題がこれによるものなのか、それとも他の何かによるものなのかはわかりません。

于 2012-12-05T23:35:02.170 に答える
26

おかげで、これは非常に役に立ちました。マップの準備ができたときに親フラグメントに通知する方がクリーンだったので、少し変更したソリューションを投稿しています。このメソッドは、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();
    }
    ...
}

それが誰かを助けることを願っています。

于 2013-04-16T21:48:59.917 に答える
15

これに対する私の解決策は次のとおりです。以前に投稿されたコードからインスピレーションを得て、クリーンアップしました。また、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;
}
于 2013-05-02T02:40:26.703 に答える
4

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です。

于 2017-03-10T07:27:33.400 に答える