doubleA
doubleA

Reputation: 2456

best practice for multiple maps

I am trying to determine the best way to deal with multiple maps. Should i be adding and removing things from a single map or switching between 2 map fragments. Ideally i think it would be better to work with fragments because i can utilize the back button easily.

My problem comes when i try to show() and hide() multiple map fragments on buttonclick. The map does not change using show()/hide(). Maybe someone can shed some light on why this is happening for me so i can better understand what is actually going on with the mapviews on show and hide. Has anyone had any issues with showing and hiding map fragments?

When i click the button the mapview does not change but i lose control unless i click the button again. It seems like the fragment is switching but not actually changing its view. I am sure that it will work correctly using replace() but this defeats the purpose of loading the maps.

package com.test.googletestmaps;
public class ControlFragment extends SherlockFragmentActivity implements
    OnClickListener {

private GoogleMap mMap;
private GoogleMap mMap2;
private SupportMapFragment gmap;
private SupportMapFragment gmap2;
private ImageButton button;
private int mapShown;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_control_fragment);
    gmap = ((SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map1));
    gmap2 = ((SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map2));

    if (savedInstanceState == null) {
        // First incarnation of this activity.
        gmap.setRetainInstance(true);
    } else {
        // Reincarnated activity. The obtained map is the same map instance
        // in the previous
        // activity life cycle. There is no need to reinitialize it.
        mMap = gmap.getMap();
    }
    if (savedInstanceState == null) {
        // First incarnation of this activity.
        gmap2.setRetainInstance(true);
    } else {
        // Reincarnated activity. The obtained map is the same map instance
        // in the previous
        // activity life cycle. There is no need to reinitialize it.
        mMap2 = gmap2.getMap();
    }
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.hide(gmap2);
    ft.commit();
    button = ((ImageButton) findViewById(R.id.cacbutton));
    button.setOnClickListener(this);
    button.setVisibility(View.VISIBLE);
    mapShown = 0;
    setUpMapIfNeeded();
}

@Override
protected void onResume() {
    super.onResume();
    setUpMapIfNeeded();
}

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 = ((SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map1)).getMap();
        // Check if we were successful in obtaining the map.
        if (mMap != null) {
            setUpMap(0);
        }

    }
    if (mMap2 == null) {
        mMap2 = ((SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map2)).getMap();

        if (mMap2 != null) {
            setUpMap(1);
        }
    }
}

private void setUpMap(int mapNumber) {
    switch (mapNumber) {
    case 0:
        mMap.getUiSettings().setZoomControlsEnabled(true);
        mMap.addMarker(new MarkerOptions().position(new LatLng(5, 5)).title("Marker for map1"));
        break;
    case 1:
        mMap2.getUiSettings().setZoomControlsEnabled(true);
        mMap2.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker for map2"));
        break;
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu with the options to show the Map and the ListView.
    getSupportMenuInflater()
            .inflate(R.menu.activity_control_fragment, menu);
    return true;
}

@Override
public void onClick(View v) {
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
    if (mapShown == 0)
    {
        ft.hide(gmap);
        ft.show(gmap2);
        mapShown = 1;
    }
    else
    {
        ft.hide(gmap2);
        ft.show(gmap);
        mapShown = 0;

    }
    ft.addToBackStack(null);
    ft.commit();

}
}

EDIT: I have found this link that explains how to show and hide a map fragment and i have tried using getView().setVisibility() but i get the same result.

Edit: This is clearly not something that is easy to solve. I have looked around and i am unable to find the solution to this. For now i will be using Add/Remove to control my fragments.

This is still not solved.... I have taken a different route. show/hide fragment does not work with multiple instances of the new google map fragments. I am not sure why and if anyone finds a solution or reason to this issue please post and share.

Upvotes: 3

Views: 7963

Answers (1)

AlexAndro
AlexAndro

Reputation: 1928

Facing this problem, after searching for a solution I have found some useful links:

Initialize MapFragment programmatically with Maps API v2

Multiple Map fragment in action bar tab

Multiple maps v2 in TabActivity

Issue while using 2 map fragments in One application

Only first map is showing with Multiple SupportMapFragment in ViewPager

Performance of multiple MapFragments (Android Map API v2)

But I decided to do it in my style:

This is how I navigate through multiple map fragments if the fragments belong to the same Activity. If map fragments belong to different Activity (I mean one MapFragment per Activity), this issue, at least in my case, was managed by Android OS so I shouldn't do anything special.

           case 1:
                if(getActivity().getSupportFragmentManager().findFragmentById(R.id.map_fragment1) == null){

                    if(getActivity().getSupportFragmentManager().findFragmentById(R.id.map_fragment2) != null){
                        FragmentManager manager = getActivity().getSupportFragmentManager();
                        FragmentTransaction ft = manager.beginTransaction();
                        ft.remove(getActivity().getSupportFragmentManager().findFragmentById(R.id.map_fragment2));
                        ft.commit();
                    }

                    FragmentManager manager1 = getActivity().getSupportFragmentManager();
                    FragmentTransaction ft1 = manager1.beginTransaction();
                    ft1.replace(R.id.frame_mapView, new Map1Fragment());
                    ft1.commit();
                }


                break;

            case 3:

                if(getActivity().getSupportFragmentManager().findFragmentById(R.id.map_fragment2) == null){

                    if(getActivity().getSupportFragmentManager().findFragmentById(R.id.map_fragment1) != null){

                        FragmentManager manager = getActivity().getSupportFragmentManager();
                        FragmentTransaction ft = manager.beginTransaction();
                        ft.remove(getActivity().getSupportFragmentManager().findFragmentById(R.id.map_fragment1));
                        ft.commit();
                    }

                    FragmentManager manager1 = getActivity().getSupportFragmentManager();
                    FragmentTransaction ft1 = manager1.beginTransaction();
                    ft1.replace(R.id.frame_mapView, new Map2Fragment());
                    ft1.commit();
                }
         break;

where Map1Fragment and Map2Fragment, each of them, extends Fragment and inflate an XML layout that contains a

<fragment
        android:id="@+id/map_fragment1"
        class="com.google.android.gms.maps.SupportMapFragment"
        />

but you can also extend just SupportMapFragment, depends on your needs.

Upvotes: 2

Related Questions