Using Actionbarsherlock with the New Supportmapfragment

Using ActionBarSherlock With the New SupportMapFragment

It all works like a charm, mainly thanks to Jake's great work on ActionBarSherlock

Here are the steps I followed:

  1. Create a SherlockMapFragment class in your actiobarsherlock library project. I simply made a copy of SherlockFragment because I also needed support for setHasOptionsMenu(true)
  2. The activity extends SherlockFragmentActivity (as usual)
  3. The fragment extends the newly created SherlockMapFragment
  4. ActionBarSherlock requires the new google-play-services_lib library
  5. Your project requires the ActionBarSherlock library. No need to include the google-play-services again, or to build against Google API.
  6. As mentionned by Graham, you have to drop support for API 7 devices: <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" />

And here's some code for a more detailed explanation:

SherlockMapFragment

package com.actionbarsherlock.app;

import com.actionbarsherlock.internal.view.menu.MenuItemWrapper;
import com.actionbarsherlock.internal.view.menu.MenuWrapper;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.google.android.gms.maps.SupportMapFragment;

import android.app.Activity;
import android.support.v4.app.Watson.OnCreateOptionsMenuListener;
import android.support.v4.app.Watson.OnOptionsItemSelectedListener;
import android.support.v4.app.Watson.OnPrepareOptionsMenuListener;

public class SherlockMapFragment extends SupportMapFragment
implements OnCreateOptionsMenuListener,
OnPrepareOptionsMenuListener,
OnOptionsItemSelectedListener {
private SherlockFragmentActivity mActivity;

public SherlockFragmentActivity getSherlockActivity() {
return mActivity;
}

@Override
public void onAttach(Activity activity) {
if (!(activity instanceof SherlockFragmentActivity)) {
throw new IllegalStateException(getClass().getSimpleName()
+ " must be attached to a SherlockFragmentActivity.");
}
mActivity = (SherlockFragmentActivity) activity;

super.onAttach(activity);
}

@Override
public void onDetach() {
mActivity = null;
super.onDetach();
}

@Override
public final void onCreateOptionsMenu(android.view.Menu menu, android.view.MenuInflater inflater) {
onCreateOptionsMenu(new MenuWrapper(menu), mActivity.getSupportMenuInflater());
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Nothing to see here.
}

@Override
public final void onPrepareOptionsMenu(android.view.Menu menu) {
onPrepareOptionsMenu(new MenuWrapper(menu));
}

@Override
public void onPrepareOptionsMenu(Menu menu) {
// Nothing to see here.
}

@Override
public final boolean onOptionsItemSelected(android.view.MenuItem item) {
return onOptionsItemSelected(new MenuItemWrapper(item));
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Nothing to see here.
return false;
}
}

The activity:

public class MainActivity extends SherlockFragmentActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}

The activity XML layout:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >

<fragment
android:id="@+id/fragment_map"
android:name=".ui.fragments.MapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:tag="tag_fragment_map" />

<fragment
android:id="@+id/fragment_help"
android:name=".ui.fragments.HelpFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:tag="tag_fragment_help" />
</FrameLayout>

The map fragment:

public class MapFragment extends SherlockMapFragment {
private GoogleMap mMap;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = super.onCreateView(inflater, container, savedInstanceState);
mMap = getMap();
return root;
}
}

Using ActionBarSherlock With Subclass of SupportMapFragment Inside Tabbed Navigation

You could extends SherlockFragment and handle the MapView yourself. This would look something like...

public class SherlockMapFragment extends SherlockFragment
{
private MapView mapView;

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

mapView = (MapView) getView().findViewById(R.id.my_map_id);
mapView.onCreate(savedInstanceState);
}

@Override
public void onResume()
{
super.onResume();
mapView.onResume();
}

@Override
public void onPause()
{
super.onPause();
mapView.onPause();
}

@Override
public void onLowMemory()
{
super.onLowMemory();
mapView.onLowMemory();
}

@Override
public void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}

@Override
public void onDestroy()
{
super.onDestroy();
mapView.onDestroy();
}
}

Nothing says you absolutely MUST use SupportMapFragment. One of the coolest parts of the new API is the ability to use the MapView as a normal View.

Google maps in an actionbarsherlock tab

I've done this in quite a few applications now. Instead of extending SupportMapFragment, you just create your own MapFragment. You can have your own layout, with a MapView view inside of it. The key is to route the lifecycle events of the Fragment to the MapView, and bobs your uncle.

Heres some example code:

MapFragment

package com.example.testapplication;

import java.util.concurrent.TimeUnit;

import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.MapsInitializer;

public class TestMapFragment extends Fragment {

private MapView mMapView;

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

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.home_fragment, container, false);

mMapView = (MapView) view.findViewById(R.id.mapview);

// inflat and return the layout
mMapView.onCreate(savedInstanceState);
mMapView.onResume();// needed to get the map to display immediately

try {
MapsInitializer.initialize(getActivity());
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
GoogleMap googleMap = mMapView.getMap();
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
return view;
}

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

/*
* Using a mapview in a fragment requires you to 'route'
* the lifecycle events of the fragment to the mapview
*/
@Override
public void onResume() {
super.onResume();
if (null != mMapView)
mMapView.onResume();
}

@Override
public void onPause() {
super.onPause();
if (null != mMapView)
mMapView.onPause();
}

@Override
public void onDestroy() {
super.onDestroy();
if (null != mMapView)
mMapView.onDestroy();
}

@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (null != mMapView)
mMapView.onSaveInstanceState(outState);
}

@Override
public void onLowMemory() {
super.onLowMemory();
if (null != mMapView)
mMapView.onLowMemory();
}
}

And the layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<com.google.android.gms.maps.MapView
android:id="@+id/mapview"
android:layout_width="match_parent"
android:layout_height="match_parent"
map:uiZoomControls="false" />
</RelativeLayout>

Google maps in an actionbarsherlock tab

I've done this in quite a few applications now. Instead of extending SupportMapFragment, you just create your own MapFragment. You can have your own layout, with a MapView view inside of it. The key is to route the lifecycle events of the Fragment to the MapView, and bobs your uncle.

Heres some example code:

MapFragment

package com.example.testapplication;

import java.util.concurrent.TimeUnit;

import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.MapsInitializer;

public class TestMapFragment extends Fragment {

private MapView mMapView;

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

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.home_fragment, container, false);

mMapView = (MapView) view.findViewById(R.id.mapview);

// inflat and return the layout
mMapView.onCreate(savedInstanceState);
mMapView.onResume();// needed to get the map to display immediately

try {
MapsInitializer.initialize(getActivity());
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
GoogleMap googleMap = mMapView.getMap();
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
return view;
}

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

/*
* Using a mapview in a fragment requires you to 'route'
* the lifecycle events of the fragment to the mapview
*/
@Override
public void onResume() {
super.onResume();
if (null != mMapView)
mMapView.onResume();
}

@Override
public void onPause() {
super.onPause();
if (null != mMapView)
mMapView.onPause();
}

@Override
public void onDestroy() {
super.onDestroy();
if (null != mMapView)
mMapView.onDestroy();
}

@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (null != mMapView)
mMapView.onSaveInstanceState(outState);
}

@Override
public void onLowMemory() {
super.onLowMemory();
if (null != mMapView)
mMapView.onLowMemory();
}
}

And the layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<com.google.android.gms.maps.MapView
android:id="@+id/mapview"
android:layout_width="match_parent"
android:layout_height="match_parent"
map:uiZoomControls="false" />
</RelativeLayout>

Google Maps Android v2 not working with ActionBarSherlock Fragment Activity

Did you include the full source from the Google Maps library? There are resources there (hence the reference to java.lang.NoClassDefFoundError: com.google.android.gms.R$styleable at com.google.android.gms.maps.GoogleMapOptions.createFromAttributes(Unknown Source)).

It's not enough to just reference the google-play-services.jar file. Double check the README.txt file at the root of the Google Play Services project.

Use ActionBarSherlock with Google map API V2

Here is my approach with a full Screen map (note that using GoogleMap API V2 within a fragment within a Tab of you ABS will add some awefull black margin when you swipe, and it's a API issue so...) :

A layout for the map fragment :

<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.package.TransparentSupportMapFragment" />

A class for the map (that could be useful to do some stuff like correcting API bugs..)

public class TransparentSupportMapFragment extends SupportMapFragment {
public TransparentSupportMapFragment() {

super();
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup view, Bundle savedInstance) {

View layout = super.onCreateView(inflater, view, savedInstance);
FrameLayout frameLayout = new FrameLayout(getActivity());
frameLayout.setBackgroundColor(getResources().getColor(android.R.color.transparent));
((ViewGroup) layout).addView(frameLayout, new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
return layout;
}
}

A FragmentActivity (or SherlockFragmentActivity)

public class ActivityGoogleMap extends SherlockFragmentActivity{

GoogleMap _googleMap;

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);

// abs
ActionBar bar = getSupportActionBar();
bar.setTitle(R.string.tle_abs);
bar.setDisplayHomeAsUpEnabled(true);

// map
_googleMap = ((TransparentSupportMapFragment) getSupportFragmentManager().findFragmentById((R.id.map))).getMap();
}

A simple transition without animation :

Intent intent = new Intent(this, ActivityGoogleMap.class);
startActivity(intent);

Now for the Manifest work :

OpenGLES2 :

    <uses-feature
android:glEsVersion="0x00020000"
android:required="true" />

Some permissions :

     <permission
android:name="com.egdigital.appetablissement.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<uses-permission android:name="android.permission.INTERNET" />
<!-- GPS LOCATION -->
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_ASSISTED_GPS" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

Your API key in Application :

<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="HERE_THE_KEY" />

Your MapActivity :

<activity
android:name=".ActivityGoogleMap"
android:configChanges="orientation"
android:label="@string/app_name" >
</activity>

Hope it will helps
good luck

ActionBar Sherlock with google Maps

you could use fragments. There you have a MapFragment to use:
http://developer.android.com/reference/com/google/android/gms/maps/MapFragment.html

or:

https://developers.google.com/maps/documentation/android/reference/com/google/android/gms/maps/SupportMapFragment

SupportMapFragment or GoogleMap is null

Note that you do not need to use a custom Fragment subclass necessarily to use Maps V2. If your fragment is just purely a map, you can create the MapFragment or SupportMapFragment from the activity and configure it there.

You do not even need to create some sort of SherlockMapFragment to be able to have a map be part of an ActionBarSherlock-based app. The regular SupportMapFragment works just fine.

If you do want to have more business smarts in your fragment, and if you are using ActionBarSherlock, and the business logic in question needs to do things related to ActionBarSherlock (e.g., contribute action items to the action bar), then and only then do you need to worry about having some sort of SherlockMapFragment.

I can confirm that this gist contains a working SherlockMapFragment. Note that it goes into the com.actionbarsherlock.app package, as it needs some package-protected access to the rest of ActionBarSherlock.

You can then subclass that, such as creating a MyMapFragment:

public class MyMapFragment extends SherlockMapFragment {
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);

if (getMap() != null) {
Log.d(getClass().getSimpleName(), "Map ready for use!");
}
}
}

You have to be a bit careful on the timing of calling getMap() -- too soon and it will return null. onActivityCreated() seems like a fairly safe time, though you are free to experiment.

Then, you just use MyMapFragment wherever you would have used SupportMapFragment:

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.commonsware.android.mapsv2.sherlock.MyMapFragment"/>

Here is the complete project containing the above code.

How to implement google maps api v2 in SherlockMapActivity

insted of shareLockMapActivity use SherlockMapFragment

create package name: com.actionbarsherlock.app inside of your Project not in sharelock lib.

add below class in to that package.

package com.actionbarsherlock.app;

import android.app.Activity;
import android.support.v4.app.Watson.OnCreateOptionsMenuListener;
import android.support.v4.app.Watson.OnOptionsItemSelectedListener;
import android.support.v4.app.Watson.OnPrepareOptionsMenuListener;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.internal.view.menu.MenuItemWrapper;
import com.actionbarsherlock.internal.view.menu.MenuWrapper;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.google.android.gms.maps.SupportMapFragment;

public class SherlockMapFragment extends SupportMapFragment implements
OnCreateOptionsMenuListener, OnPrepareOptionsMenuListener,
OnOptionsItemSelectedListener {
private SherlockFragmentActivity mActivity;

public SherlockFragmentActivity getSherlockActivity() {
return mActivity;
}

@Override
public void onAttach(Activity activity) {
if (!(activity instanceof SherlockFragmentActivity)) {
throw new IllegalStateException(getClass().getSimpleName()
+ " must be attached to a SherlockFragmentActivity.");
}
mActivity = (SherlockFragmentActivity) activity;

super.onAttach(activity);
}

@Override
public void onDetach() {
mActivity = null;
super.onDetach();
}

@Override
public final void onCreateOptionsMenu(android.view.Menu menu,
android.view.MenuInflater inflater) {
onCreateOptionsMenu(new MenuWrapper(menu),
mActivity.getSupportMenuInflater());
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Nothing to see here.
}

@Override
public final void onPrepareOptionsMenu(android.view.Menu menu) {
onPrepareOptionsMenu(new MenuWrapper(menu));
}

@Override
public void onPrepareOptionsMenu(Menu menu) {
// Nothing to see here.
}

@Override
public final boolean onOptionsItemSelected(android.view.MenuItem item) {
return onOptionsItemSelected(new MenuItemWrapper(item));
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Nothing to see here.
return false;
}
}

how use above class:

public class MyMapFragment extends SherlockMapFragment {

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

if (getMap() != null) {
Log.e(getClass().getSimpleName(), "Map ready for use!");
CameraUpdate center = CameraUpdateFactory.newLatLng(new LatLng(
23.0333, 72.6167));
CameraUpdate zoom = CameraUpdateFactory.zoomTo(10);

getMap().moveCamera(center);
getMap().animateCamera(zoom);

addMarker(getMap(), Double.parseDouble(latlong[0]),
Double.parseDouble(latlong[1]), name, "" + sni);

}

}

private void addMarker(GoogleMap map, double lat, double lon,
String string, String string2) {
map.addMarker(new MarkerOptions()
.position(new LatLng(lat, lon))
.title(string)
.snippet(string2)
.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));
}
}

add above fragment in any Activity like below

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<fragment class="com.dj_android.MyMapFragment"
android:id="@+id/titles"
android:layout_width="match_parent" android:layout_height="match_parent" />
</FrameLayout>

Edited:

Please learn what is fragment.

how use fragment in Activity.



Related Topics



Leave a reply



Submit