Saturday, March 30, 2013

Retain instance of MapFragment

In the last exercise of "Dual MapFragment", if the device orientation changed, the display area and zoom level will be kept, but the added marker will disappear.

In this exercise, we are going to modify map2 from last post, to retain instance after orientation changed.

Retain instance of MapFragment


To keep the markers after orientation changed, create custom MapFragment (RetainMapFragment), override onActivityCreated() call setRetainInstance(true).
package com.example.androidmapex;

import android.os.Bundle;

import com.google.android.gms.maps.MapFragment;

public class RetainMapFragment extends MapFragment {

 @Override
 public void onActivityCreated(Bundle savedInstanceState) {
  super.onActivityCreated(savedInstanceState);
  setRetainInstance(true);
 }

}


Modify layout file to use "com.example.androidmapex.RetainMapFragment" class on map2.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <fragment
        android:id="@+id/map1"
        android:layout_width="match_parent"
        android:layout_height="0px"
        android:layout_weight="2"
        android:layout_margin="5px"
        class="com.google.android.gms.maps.MapFragment"/>
    <fragment
        android:id="@+id/map2"
        android:layout_width="match_parent"
        android:layout_height="0px"
        android:layout_weight="3"
        android:layout_margin="5px"
        class="com.example.androidmapex.RetainMapFragment"/>

</LinearLayout>


Modify MainActivity to use define myMapFragment2 as RetainMapFragment.
package com.example.androidmapex;

import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.BitmapDescriptor;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

import android.os.Bundle;
import android.app.Activity;
import android.app.FragmentManager;

public class MainActivity extends Activity{
 
 private GoogleMap myMap1, myMap2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        FragmentManager myFragmentManager = getFragmentManager();
        MapFragment myMapFragment1 = 
          (MapFragment)myFragmentManager.findFragmentById(R.id.map1);
        RetainMapFragment myMapFragment2 = 
          (RetainMapFragment)myFragmentManager.findFragmentById(R.id.map2);
        myMap1 = myMapFragment1.getMap();
        myMap2 = myMapFragment2.getMap();
        
        myMap1.setOnMapLongClickListener(my1_OnMapLongClickListener);
        myMap2.setOnMapLongClickListener(my2_OnMapLongClickListener);
    }
 
 OnMapLongClickListener my1_OnMapLongClickListener =
   new OnMapLongClickListener(){

    @Override
    public void onMapLongClick(LatLng point) {
     myMap1.addMarker(new MarkerOptions()
          .position(point)
          .title(point.toString()));
    }
  
 };
 
 OnMapLongClickListener my2_OnMapLongClickListener =
   new OnMapLongClickListener(){

    @Override
    public void onMapLongClick(LatLng point) {
     
     BitmapDescriptor bitmapDescriptor = 
       BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE);
     
     myMap2.addMarker(new MarkerOptions()
          .position(point)
          .icon(bitmapDescriptor)
          .title(point.toString()));
    }
  
 };
    
}


Related:
- Retain data using Fragment API setRetainInstance()


download filesDownload the files.



The series:
A simple example using Google Maps Android API v2, step by step.

1 comment:

Manuel said...

Very interesting post by the way even though it is old! I am just learning how to use this. I am interested how would this work if the MainActivity would extend AppCompatActivity and if you would use getMapAsync instead of the getMap that is deprecated. This would implement the onMapReadyCallBack. how would you do this in this case. Thanks in advance for your support!