HowTo: ActionBarSherlock + MapFragment + ListFragment

Today I’ll write about how to have 2 fragments in one Activity, one of them containing a ListView (for example), and the other one containing a MapView, and all of this with a supercool ActionBarSherlock! The perfect combo!

The problem

It’s quite simple: if you want to use fragments with a MapView, you’re not allowed to do it in an easy way.

There’s no MapFragment that can be held by a FragmentActivity or a MapFragmentActivity that can hold both a MapView and some fragments #fail. So, what’s the solution?

The workaround

Fortunately, there’s always people who do cool libraries. One example is “android-support-v4-googlemaps“. It’s essentially a copy of the Android Compatibility Library but the FragmentActivity class extends MapActivity instead of Activity, so we have functionality of a MapActivity with fragments.

The setting up

There are the steps:

  1. First of all you should take a look at my last post Using an ActionBar in your Android app with ActionBarSherlock and follow the steps 1 to 6 in the part named “The code“, just 1 to 6, not 7. If you already have the ActionBarSherlock in your workspace, you can skip this step.
  2. Create a copy of the ActionBarSherlock library project and rename it to something like “Sherlock-ActionBar-GoogleMaps-lib-4.0.0“, we will work on that copy.
  3. Then download the last version of the android-support-v4-googlemaps library here.
  4. Now remove the android-support-v4.jar file from the library project build path, copy the file you downloaded (which name should be something like android-support-v4-r6-googlemaps.jar) and paste it to the libs folder in the library. It’s also needed to add this new jar to the Build path.
  5. After that, change the target SDK version of the ActionBarSherlock to the Google APIs SDK (for example Google APIs 4.0).
  6. Create a new project called “Maps with fragments”, that targets Google APIs SDK 4.0.
  7. Add the “Sherlock-ActionBar-GoogleMaps-lib-4.0.0” as a library project in the project that we just created and add the android-support-v4-r6-googlemaps.jar library to the new project’s build path.

The codes

We’re done with the setup. Now it’s time for the code. Basically what we’ll be doing is have an Activity that extends SherlockFragmentActivity. Then we’ll need to create a static class with a static MapView in it that we will use as an “Exchanger” between the Activity and the MapFragment. Our activity will create a new MapView object and store it into the Exchanger.

We also need to create a class (the MapFragment) that extends SherlockFragment. This Fragment will use the Exchanger’s MapView as content view.

Then we will be able to replace that fragment with another one (for example a ListFragment).

That was a basic explanation of the “Hack”.

Here you have the source for the class MapswithfragmentsActivity.java:

package com.xrigau.mapsfragments;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;

import com.actionbarsherlock.app.SherlockFragment;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.app.SherlockListFragment;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.google.android.maps.MapView;

public class MapswithfragmentsActivity extends SherlockFragmentActivity {
	
	private MapFragment mMapFragment;
	private MyListFragment mMyListFragment;
	
	// We use this fragment as a pointer to the visible one, so we can hide it easily.
	private Fragment mVisible = null;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        // We instantiate the MapView here, it's really important!
        Exchanger.mMapView = new MapView(this, "INSERT_YOUR_MAP_API_KEY_HERE"); // TODO: Replace for API Key!
        
        setupFragments();
        // We manually show the list Fragment.
        showFragment(mMyListFragment);
    }

	/**
	 * This method does the setting up of the Fragments. It basically checks if
	 * the fragments exist and if they do, we'll hide them. If the fragments
	 * don't exist, we create them, add them to the FragmentManager and hide
	 * them.
	 */
	private void setupFragments() {
		final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();

		// If the activity is killed while in BG, it's possible that the
		// fragment still remains in the FragmentManager, so, we don't need to
		// add it again.
		mMapFragment = (MapFragment) getSupportFragmentManager().findFragmentByTag(MapFragment.TAG);
        if (mMapFragment == null) {
        	mMapFragment = new MapFragment();
        	ft.add(R.id.fragment_container, mMapFragment, MapFragment.TAG);
        }
        ft.hide(mMapFragment);
        
        mMyListFragment = (MyListFragment) getSupportFragmentManager().findFragmentByTag(MyListFragment.TAG);
        if (mMyListFragment == null) {
        	mMyListFragment = new MyListFragment();
        	ft.add(R.id.fragment_container, mMyListFragment, MyListFragment.TAG);
        }
        ft.hide(mMyListFragment);
        
        ft.commit();
	}
	
	/**
	 * This method shows the given Fragment and if there was another visible
	 * fragment, it gets hidden. We can just do this because we know that both
	 * the mMyListFragment and the mMapFragment were added in the Activity's
	 * onCreate, so we just create the fragments once at first and not every
	 * time. This will avoid facing some problems with the MapView.
	 * 
	 * @param fragmentIn
	 *            The fragment to show.
	 */
	private void showFragment(Fragment fragmentIn) {
		if (fragmentIn == null) return;
		
		final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
		ft.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
		
		if (mVisible != null) ft.hide(mVisible);
		
		ft.show(fragmentIn).commit();
		mVisible = fragmentIn;
	}
	
    @Override
	public boolean onCreateOptionsMenu(Menu menu) {
    	// Inflate the menu with the options to show the Map and the List.
    	getSupportMenuInflater().inflate(R.menu.menu, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.ic_list:
			// Show mMyListFragment.
			showFragment(mMyListFragment);
			return true;
			
		case R.id.ic_map:
			// Show mMapFragment.
			showFragment(mMapFragment);
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	/**
	 * This class acts as an exchanger between the Activity and the MapFragment,
	 * so if you want, you can put the MapFragment class in a separate java
	 * file.
	 * 
	 * @author Xavi
	 * 
	 */
	public static class Exchanger {
		// We will use this MapView always.
    	public static MapView mMapView;
    }
	
	/**
	 * This is our ListFragment class. You can put it in a separate java file.
	 * 
	 * @author Xavi
	 * 
	 */
	public static class MyListFragment extends SherlockListFragment {

		public static final String TAG = "listFragment";
		
		private final String[] mItems = { "List Item 1", "List Item 2",
				"List Item 3", "List Item 4", "List Item 5", "List Item 6",
				"List Item 7", "List Item 8", "List Item 9", "List Item 10" };
		
		public MyListFragment() {}
		
		@Override
		public void onCreate(Bundle arg0) {
			super.onCreate(arg0);
			setRetainInstance(true);
		}

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup vg, Bundle data) {
			// Inflate the ListView layout file.
			return inflater.inflate(R.layout.list_fragment, null);
		}

		@Override
		public void onViewCreated(View arg0, Bundle arg1) {
			super.onViewCreated(arg0, arg1);
			setListAdapter(new ArrayAdapter<String>(getSherlockActivity(), android.R.layout.simple_list_item_1, android.R.id.text1, mItems));
		}
	}
	
	/**
	 * This is the Fragment class that will hold the MapView as its content
	 * view. You can put it in a separate java file.
	 * 
	 * @author Xavi
	 * 
	 */
	public static class MapFragment extends SherlockFragment {

		public static final String TAG = "mapFragment";
		
		public MapFragment() {}
		
		@Override
		public void onCreate(Bundle arg0) {
			super.onCreate(arg0);
			setRetainInstance(true);
		}
		
		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup vg, Bundle data) {
			// The Activity created the MapView for us, so we can do some init stuff.
			Exchanger.mMapView.setClickable(true);
			Exchanger.mMapView.setBuiltInZoomControls(true); // If you want.

			/*
			 * If you're getting Exceptions saying that the MapView already has
			 * a parent, uncomment the next lines of code, but I think that it
			 * won't be necessary. In other cases it was, but in this case I
			 * don't this should happen.
			 */
			/*
			 * final ViewGroup parent = (ViewGroup) Exchanger.mMapView.getParent();
			 * if (parent != null) parent.removeView(Exchanger.mMapView);
			 */
			
			return Exchanger.mMapView;
		}
	}
}

Here you have the source for the main.xml layout file:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <!-- This FrameLayout will be the PlaceHolder of the Fragments. -->
    <FrameLayout android:id="@+id/fragment_container"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</LinearLayout>

There’s the source for the list_fragment.xml layout file:

<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/list"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
</ListView>

That’s the menu.xml file:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/ic_list"
        android:icon="@android:drawable/ic_menu_agenda"
        android:showAsAction="ifRoom|withText"
        android:title="List"/>
    <item
        android:id="@+id/ic_map"
        android:icon="@android:drawable/ic_menu_mapmode"
        android:showAsAction="ifRoom|withText"
        android:title="Map"/>

</menu>

Finally the AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
	package="com.xrigau.mapsfragments"
	android:versionCode="1"
	android:versionName="1.0" >
	
	<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="15"/>
	
	<!-- We need Internet in order to load the maps. -->
	<uses-permission android:name="android.permission.INTERNET" />

	<!-- Set the theme in order to use the ActionBarSherlock. -->
	<application android:theme="@style/Theme.Sherlock.Light.DarkActionBar"
		android:icon="@drawable/ic_launcher"
		android:label="@string/app_name" >
		
	    <!-- We need to tell Android that we'll be using Google Maps Library. -->
	    <uses-library android:name="com.google.android.maps" />
	    
		<activity
			android:name=".MapswithfragmentsActivity"
			android:label="@string/app_name" >
			<intent-filter>
				<action android:name="android.intent.action.MAIN" />

				<category android:name="android.intent.category.LAUNCHER" />
			</intent-filter>
		</activity>
	</application>

</manifest>

And you can download the complete source for this tutorial in this link http://dl.dropbox.com/u/2397504/xrigau-abs_map_list_v1.zip.

So, the final result is:
The result!
Really nice! 🙂

To end up, I just hope that this can help somebody and if you have questions, please comment and ask what you want and I’ll try to do my best to help you.

Tags: , , , , ,

About Xavi Rigau

I'm an Android enthusiast! I'm finishing a degree in IT science while I work as Android Developer in a company in Barcelona. I also try to develop my own apps. My dog Fiona helps me a lot in that! She's quite good.

43 responses to “HowTo: ActionBarSherlock + MapFragment + ListFragment”

  1. m3n0R says :

    Ei Xavi!!

    He estat investigant sobre tu, per què m’ha sorprès el teu post i he vist que treballaves a Tempos 21, per tant deus ser el becari (o no) del Sergi, oi?

    🙂

    soc en m3n0R de CatDroid 😀 (encara no ens coneixem en persona per això)

    Molt bò el post que has fet, a més crec que s’adapta al que jo estava cercant, per què ara amb la actionbar 4.0, jo tenia fet un Tab amb 2 fragments (un fragment amb mapa i un altre amb llista) que penjaven d’una FragmentMapActivity, el Jake Wharton l’ha eliminat de la nova versió per passar a SherlockMapActivity :P, per la qual cosa, el teu codi s’adaptaria bé per aquesta nova versió!!!

    Moltes gràcies crack, molt bon post 😛

    Salut!

  2. m3n0R says :

    Per cert, amb la r7 de suport a google maps, hi ha un problema a la classe:

    SherlockFragmentActivity:

    protected void supportInvalidateOptionsMenu() {
    if (DEBUG) Log.d(TAG, “[supportInvalidateOptionsMenu]”);

    invalidateOptionsMenu();
    }

    he de fer la funció pública. T’ho fico aquí per si algú mes li passa

  3. m3n0R says :

    Molt de gust 😉

    Per cert… com t’he dit a l’altre post, estic desperate…

    De fet, he obert els teus dos projectes directament, i em segueix donant el mateix error de Dalvik…

    [2012-04-05 12:17:48 – Maps with fragments] Dx
    UNEXPECTED TOP-LEVEL EXCEPTION:
    java.lang.IllegalArgumentException: already added: Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompat;
    [2012-04-05 12:17:48 – Maps with fragments] Dx at com.android.dx.dex.file.ClassDefsSection.add(ClassDefsSection.java:123)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at com.android.dx.dex.file.DexFile.add(DexFile.java:163)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at com.android.dx.command.dexer.Main.processClass(Main.java:486)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at com.android.dx.command.dexer.Main.processFileBytes(Main.java:455)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at com.android.dx.command.dexer.Main.access$400(Main.java:67)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:394)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:245)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:131)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:109)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at com.android.dx.command.dexer.Main.processOne(Main.java:418)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at com.android.dx.command.dexer.Main.processAllFiles(Main.java:329)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at com.android.dx.command.dexer.Main.run(Main.java:206)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at java.lang.reflect.Method.invoke(Method.java:597)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at com.android.ide.eclipse.adt.internal.build.DexWrapper.run(DexWrapper.java:180)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at com.android.ide.eclipse.adt.internal.build.BuildHelper.executeDx(BuildHelper.java:702)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at com.android.ide.eclipse.adt.internal.build.builders.PostCompilerBuilder.build(PostCompilerBuilder.java:646)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:728)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:199)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:321)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:396)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at org.eclipse.core.internal.resources.Project$1.run(Project.java:618)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2344)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at org.eclipse.core.internal.resources.Project.internalBuild(Project.java:597)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at org.eclipse.core.internal.resources.Project.build(Project.java:124)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at com.android.ide.eclipse.adt.internal.project.ProjectHelper.doFullIncrementalDebugBuild(ProjectHelper.java:978)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at com.android.ide.eclipse.adt.internal.launch.LaunchConfigDelegate.launch(LaunchConfigDelegate.java:147)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:854)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:703)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at org.eclipse.debug.internal.ui.DebugUIPlugin.buildAndLaunch(DebugUIPlugin.java:937)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at org.eclipse.debug.internal.ui.DebugUIPlugin$8.run(DebugUIPlugin.java:1141)
    [2012-04-05 12:17:48 – Maps with fragments] Dx at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
    [2012-04-05 12:17:48 – Maps with fragments] Dx 1 error; aborting
    [2012-04-05 12:17:48 – Maps with fragments] Conversion to Dalvik format failed with error 1

    • Xavi Rigau says :

      Has intentat de no utilitzar la última compatibility library i fer servir l’anterior (jo el post el vaig escriure usant l’anterior i em va perfecte…).
      La veritat és que ara estic a la feina i ho tinc una mica complicat… xD

      El ADT plugin i els SDK tools els tens a la última versió veritat? Que no sigui que alguna cosa s’hagi quedat pendent d’actualiztar. Normalment el Dalvik format error 1 aquet és degut a problemes amb les llibreries/dependències…

      • m3n0R says :

        Faig servir únicament el zip que tu acabes de ficar per aquí… i em dona aquest error de Dalvik.

        Hauria de modificar alguna cosa o amb això ja tiraria?

        En cas que a tu et funciones, no series tan amable de passarme un zip amb el teu actionsherlockbar amb google maps inclos, i dirme que he de ficar exactament al meu projecte. (que he de tenir tant al build path com a la carpeta libs del MEU projecte –> que no se si he de tenir algo o no… tinc el cap com un timbal..)

      • Miroslav says :

        I am having the same trouble as described. But I did not understand the answer…

  4. m3n0R says :

    Aquí una pantalla de com ho tinc:

    • Xavi Rigau says :

      Has de borrar el “android-support-v4.jar” que hi ha a les carpetes libs tant de la llibreria Sherlock com del teu projecte. És a dir que tant a la llibreria Sherlock com al projecte que la fa servir, a la carpeta libs només ha d’haver-hi el fitxer “android-support-v4-r6-googlemaps.jar”. Tot el demés és correcte! Prova i em dius

  5. m3n0R says :

    Perfecte!!! Per fi!!!!

    Es que m’estava menjant el tarro, per què no hi havia manera… de fet ja stic utilitzant la versió r7 sense problemes!

    Al pas 4 deies:
    “Now remove the android-support-v4.jar file from the library project build path, copy the file you downloaded (which name should be something like android-support-v4-r6-googlemaps.jar) and paste it to the libs folder in the library. It’s also needed to add this new jar to the Build path.”

    Amb això entenia que nomes ho havia de borrar del build path, no del directori libs, no es així?

    • Xavi Rigau says :

      Ésque aquest post el vaig fer com 2 dies abans de que sortís el nou ADT plugin i no l’he actualitzat. Abans podies tenir diverses versions d’una sola llibreria a la carpeta libs mentre que no les tinguèssis al build path alhora.

      El problema del nou ADT és que t’hagafa tot el que tinguis a la carpeta libs i t’ho referencia directament com a Android Dependencies (que és més o menys el mateix que tenir-ho al build path). Per tant tenies repetida la llibreria de support library en diferents versions i per això petava.

      Ja sé, hauria d’actualitzar el post…
      M’alegro d’haver servit d’ajuda!

  6. manelizzard says :

    Gràcies Xavi! A mi també m’ha servit de molta ajuda 😉

    A sobre, llegir els comentaris en català… gran comunitat d’Android en Català ^^

  7. Bernat Borras-Parone (@bbpp) says :

    Bones!

    Hi ha alguna manera de fer aixó pero integrat directamente a la actionabrsherlock? O de fer una especie de MapFragment?

    • Xavi Rigau says :

      Hola Bernat.

      Diria que l’únic que pots fer és utilitzar la SherlockMapActivity, però llavors no pots fer servir fragments en versions anteriors a Android 3.0 (ja que les activities no poden contenir fragments i SherlockMapActivity exten MapActivity que exten Activity). Per tant en aquet cas hauries de tenir les vistes MapView i ListView a la mateixa Activity i tenir la lògica tant del mapa com de la llista en aquesta.

      El tema del MapFragment no es pot fer (sense canviar l’activitat), ja que el MapView només funciona si està inclosa en una MapActivity, si no, llança una excepció.

      Em sembla molt extrany que els senyors de Google no hagin creat un MapFragment encara, però mira, es veu que tindran altres coses més divertides a fer…

      Espero haver-te ajudat.

  8. mutkan says :

    Hi, why did you use static classes?

  9. fabio says :

    Hi Xavi,

    I followed the tutorial and I got an error “java.lang.IllegalArgumentException: MapViews can only be created inside instances of MapActivity.” So I downloaded your files from the Dropbox, and I still have the same error… it seems that doesn’t like:

    Exchanger.mMapView = new MapView(this, “mygooglekey”);

    Any ideas??

    Thanks,

    Fabio

  10. mydailyservings says :

    I got this error inside the fragment class that extends SherlockListFragment

    public boolean onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu) {
    com.actionbarsherlock.view.MenuInflater inflater = getSupportMenuInflater();
    inflater.inflate(R.menu.main_screen_menu, menu);

    }

    getSupportMenuInflater(); is being marked red.

    please help.

  11. Christian says :

    Thank you very much for this Tutorial!! Great!

  12. Lindo says :

    I wrote a little library, mashing up the LocalActivityManager-based solutions for the MapFragment problem:

    https://github.com/coreform/android-tandemactivities

  13. SL says :

    For Maven users. I’m using NetBeans 7.2 RC1 with maven plug-in.
    Better solution is to install android-support-v4-googlemaps-r10.jar into the Maven Local Repository. For this:
    1.Make some temporary directory, for example C:\TEMP\S4
    2.Copy into the directory android-support-v4-googlemaps-r10.jar
    3.Rename it to android-support-v4.jar
    4.Run in this directory in command line:
    mvn -e install:install-file -Dfile=android-support-v4.jar -DgroupId=com.google.android -DartifactId=support-v4 -Dversion=r10M -Dpackaging=jar
    5.Make changes into pom.xml file in directory Sherlock-ActionBar-GoogleMaps-lib-4.0.0\library\
    5.1.Add new dependency:

    com.google.android.maps
    maps
    15_r2
    provided

    5.2.Add version of support-v4 dependency

    com.google.android
    support-v4
    r10M

    6.Run in Sherlock-ActionBar-GoogleMaps-lib-4.0.0\library\ directory command line command:
    mvn clean install
    7.If all ok now you can in Activity extended from SherlockFragmentActivity override method:
    @Override
    protected boolean isRouteDisplayed() {
    return false;
    }
    In usual version of SherlockActionBar you can’t.
    8.Add into your project pom file version of support dependecy

    com.google.android
    support-v4
    r10M

    9.Build your project
    10.Enjoy!

  14. SL says :

    If you use ActionBarSherlock, then you don’t need any static classes and other complications, just add in onCreate method of SherlockActivity:

    public class MainScreen extends SherlockFragmentActivity {
    @Override
    protected boolean isRouteDisplayed() {
    return false;
    }

    MapView mMapView = null;

    @Override
    public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    mMapView = new MapView(this, getString(R.string.mapkey));
    }
    }

    Then in SherlockFragment you must override 2 methods:

    public class LocationFragment extends SherlockFragment {
    RelativeLayout mRelativeLayout = null;

    @Override
    public View onCreateView(LayoutInflater inflater,
    ViewGroup container, Bundle savedInstanceState) {
    MapView mv = ((MainScreen)getSherlockActivity()).mMapView;
    View view = inflater.inflate(R.layout.location_fragment, container, false);
    RelativeLayout rl = (RelativeLayout) view.findViewById(R.id.map_place);
    if (mv.getParent() == null) {
    rl.addView(mv);
    }
    mRelativeLayout = rl;
    return view;
    }

    @Override
    public void onDestroyView() {
    MapView mv = ((MainScreen)getSherlockActivity()).mMapView;
    RelativeLayout rl = mRelativeLayout;
    if (mv.getParent() == rl) {
    rl.removeView(mv);
    }
    super.onDestroyView();
    }
    }

    That’s all!

  15. AndroiJavaThon says :

    As much as i enjoy your tutorials.there is always something you forget to mention.Okay,i followed your lead and what did i get errors in the newly created library source code that i had to change some of them and am stuck also at some.please give details on if one encounters this that he/she should do this,this,and that.

    • Xavi Rigau says :

      Sorry about that, this tutorials are a bit old (the ADT plugin has changed how it treats library projects since that), so there are some things that should change a little. I’ll try to review the tutorials and rewrite them when I have some time, but now I am really busy now.

      Here you have a project with a good implementation of a mapview inside tabs using fragments: https://github.com/rallat/android-example See if it can help you

  16. Mike says :

    This solution doesn’t work on Android 4.1.1 (Asus Transformer Tablet). It crashes when clicking on the map or list button. What’s going on there?

    • Xavi Rigau says :

      Can you post your stack trace from Logcat?

      • Pedro Nóbrega da Costa says :

        i have the same error as mike.
        here is locat trace:

        E/AndroidRuntime(21065): FATAL EXCEPTION: main
        E/AndroidRuntime(21065): java.lang.IllegalStateException: Cannot interact with object designed for temporary instance passing. Make sure you using both SherlockFragmentActivity and SherlockFragment.
        at com.actionbarsherlock.internal.view.menu.MenuItemMule.getItemId(MenuItemMule.java:71)
        at android.app.Activity.onMenuItemSelected(Activity.java:2554)
        at android.support.v4.app.FragmentActivity.onMenuItemSelected(Unknown Source)
        at com.actionbarsherlock.app.SherlockFragmentActivity.onMenuItemSelected(SherlockFragmentActivity.java:283)
        at com.actionbarsherlock.ActionBarSherlock.callbackOptionsItemSelected(ActionBarSherlock.java:587)
        at com.actionbarsherlock.internal.ActionBarSherlockNative.dispatchOptionsItemSelected(ActionBarSherlockNative.java:78)
        at com.actionbarsherlock.app.SherlockFragmentActivity.onMenuItemSelected(SherlockFragmentActivity.java:193)
        at com.android.internal.policy.impl.PhoneWindow.onMenuItemSelected(PhoneWindow.java:980)
        at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:735)
        at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:149)
        at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:874)
        at com.android.internal.view.menu.ActionMenuView.invokeItem(ActionMenuView.java:547)
        at com.android.internal.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:115)
        at android.view.View.performClick(View.java:4202)
        at android.view.View$PerformClick.run(View.java:17340)
        at android.os.Handler.handleCallback(Handler.java:725)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:5039)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
        at dalvik.system.NativeStart.main(Native Method)

  17. Chris says :

    Thank you for that post! Works like charm!

  18. Sagar Trehan says :

    Thanks for this wonderful post

  19. Simone Murtas says :

    Hi!! I changed the Map Key but get only white tiles! What the problem? The key is correct and the Internet permission is already setted up

  20. Nacho says :

    How I can do to use the SherlockActionBar together with maps of the new API version 2 for Google maps (which is employed from December 2012) that implements the class maps using GoogleMap?

    Thank you very much.

  21. Elad Nava says :

    You saved me from countless hours of rewriting overlays for Google’s new GoogleMap object. Thanks!

  22. Elijah Keya says :

    hey, nice tutorial, need some help here, I am trying to modify my ListView in sherlock fragment but it is failing at some point

    @Override
    protected void onPostExecute(SimpleAdapter adapter) {

    Toast.makeText(getActivity().getBaseContext(), “grrrr”.toString(), Toast.LENGTH_SHORT).show();

    // Each row in the list stores country name, currency and flag
    List<HashMap> aList = new ArrayList<HashMap>();

    // Setting adapter for the listview
    //mListView.setAdapter(adapter);

    for(int i=0;i<adapter.getCount();i++){
    HashMap hm = (HashMap) adapter.getItem(i);
    String imgUrl = (String) hm.get(“url_path”);
    ImageLoaderTask imageLoaderTask = new ImageLoaderTask();

    @SuppressWarnings(“unused”)
    HashMap hmDownload = new HashMap();
    hm.put(“url_path”,imgUrl);
    hm.put(“position”, i);

    // Starting ImageLoaderTask to download and populate image in the listview
    imageLoaderTask.execute(hm);
    }

    }

    Setting adapter, any help

  23. Lavona Octave says :

    Thank you for sharing superb informations. Your web-site is very cool. I’m impressed by the details that you’ve on this site. It reveals how nicely you understand this subject. Bookmarked this website page, will come back for extra articles. You, my pal, ROCK! I found just the information I already searched everywhere and simply couldn’t come across. What a perfect web-site.

Leave a reply to Xavi Rigau Cancel reply