Skip to content Skip to sidebar Skip to footer

Android Mapview With Fragments Can't Be Added Twice?

I am using the android compatibility class with the hack for using mapviews in a fragment found here: https://github.com/petedoyle/android-support-v4-googlemaps Unfortunately, what

Solution 1:

I encountered the same issue. Here is how I solved it :

  • As it should be only one instance of the mapView in the activity, I initialize it in onCreate method in Activity :

    publicvoidonCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // initialize MapView programmatically to be used in Fragment :this.mActivityMapView = new MapView(MainActivity.this, getString(R.string.debug_mapview_apikey));
    
        setContentView(R.layout.activity_main);
    }
    
  • Then I recover it in the fragment onCreateView method :

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        this.mMapView = ((MainActivity) getActivity()).getMapView();
        returnthis.mMapView;
    }
    
  • And I destroy it in the fragment onDestroy method :

    publicvoidonDestroy() {
        NoSaveStateFrameLayoutparentView= (NoSaveStateFrameLayout) this.mMapView.getParent();
        parentView.removeView(this.mMapView);
        super.onDestroy();
    }
    

Solution 2:

You might want to remove the map view in the onPause method (instead of the onDestroy method)

publicvoidonPause() {
    NoSaveStateFrameLayoutparentView= (NoSaveStateFrameLayout) this.mMapView.getParent();
    parentView.removeView(this.mMapView);
    super.onPause();}

This way, you can add a MapFragment to the backstack. (FragmentTransaction.addToBackStack prevents a fragment from being destroyed)

Solution 3:

Max and Bleeker's answers work well but you need to take special care if you want to support screen orientation changes, as I do. It turns out when you rotate the screen, it will call OnCreateView again without calling the onPause method, thus adding the mapview twice. To fix it, inside OnCreateView I did the following:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    this.mMapView = ((MyGameActivity) getActivity()).getMapView();
    if (this.mMapView.getParent()!=null)
    {
        NoSaveStateFrameLayout parentView = (NoSaveStateFrameLayout) this.mMapView.getParent();
        parentView.removeView(this.mMapView);
    }
    returnthis.mMapView;
}

Solution 4:

I tried to get a simple solution to this problem. On the class that handles my View details (a RelativeLayout extension), I declared a private static MapView myMapView;.

Then, override onFinishInflate() method like the following code snippet:

@OverrideprotectedvoidonFinishInflate() {  
    super.onFinishInflate();

    //myMapView = (MapView) findViewById(R.id.map_view);if (myMapView==null) 
        myMapView = newMapView(context, getResources().getString(R.string.map_view_api_key));  
    if (myMapView.getParent() != null)
        ((ViewGroup)myMapView.getParent()).removeView(myMapView);

    myMapView.setClickable(true);
    myMapView.setEnabled(true);
    RelativeLayout.LayoutParamslp=newRelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
    myMapView.setLayoutParams(lp);          
    this.addView(myMapView);

}

This way you have only one instance of MapView.

Solution 5:

Here is how i solved this issue in case of Fragment.

Create the Layout

 <LinearLayout
        android:id="@+id/ll_mapcontainer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" />

You can place this like layout anywhere in your XML File where you want to display the map

Now the Code will be Like this.

package com.yuviii.sample;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.yuviii.sample.R;

/**
 * Created by yubraj Poudel on 12/20/15.
 */publicclassContactUsFragmentextendsFragment  {
    staticfinalLatLngPRACTICAL_ANSWER_LOCATION=newLatLng(53.558, 9.927);
    private SupportMapFragment fragment;
    private GoogleMap map;

    @Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
       Viewv= inflater.inflate(R.layout.page_contactus, container, false);
        return v;
    }



    @OverridepublicvoidonActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
                    initializeMap();
    }

    privatevoidinitializeMap() {

        FragmentManagerfm= getChildFragmentManager();
        fragment = (SupportMapFragment) fm.findFragmentById(R.id.ll_mapcontainer);
        if (fragment == null) {
            fragment = SupportMapFragment.newInstance();
            fm.beginTransaction().replace(R.id.ll_mapcontainer, fragment).commit();
        }

    }
    @OverridepublicvoidonResume() {
        super.onResume();
        if (map == null) {
            map = fragment.getMap();
            map.addMarker(newMarkerOptions().position(PRACTICAL_ANSWER_LOCATION));
        }
    }   
}

This works for me. Enjoy !!!

Post a Comment for "Android Mapview With Fragments Can't Be Added Twice?"