MapView en un fragmento (Honeycomb)

Ahora que el SDK final está fuera con google apis – ¿cuál es la mejor manera de crear un fragmento con un MapView? MapView necesita una MapActivity para funcionar correctamente.

Tener la actividad de gestión de los fragmentos heredar de MapActivity (mala solución, ya que va en contra de la idea de que Fragmentos son autónomos) y el uso de un diseño regular xml basado no funciona. Recibo una NullPointerException en MapActivity.setupMapView ():

 E / AndroidRuntime (597): Causado por: java.lang.NullPointerException
 E / AndroidRuntime (597): en com.google.android.maps.MapActivity.setupMapView (MapActivity.java:400)
 E / AndroidRuntime (597): en com.google.android.maps.MapView. (MapView.java:289)
 E / AndroidRuntime (597): en com.google.android.maps.MapView. (MapView.java:264)
 E / AndroidRuntime (597): en com.google.android.maps.MapView. (MapView.java:247)

Mi segunda idea fue crear el MapView de forma programática y pasar la actividad asociada (a través de getActivity ()) como Contexto al constructor MapView. No funciona:

 E / AndroidRuntime (834): Causado por: java.lang.IllegalArgumentException: MapViews sólo se puede crear dentro de instancias de MapActivity.
 E / AndroidRuntime (834): en com.google.android.maps.MapView. (MapView.java:291)
 E / AndroidRuntime (834): en com.google.android.maps.MapView. (MapView.java:235)
 E / AndroidRuntime (834): en de.foo.FinderMapFragment.onCreateView (FinderMapFragment.java:225)
 E / AndroidRuntime (834): en android.app.FragmentManagerImpl.moveToState (FragmentManager.java:708)
 E / AndroidRuntime (834): en android.app.FragmentManagerImpl.moveToState (FragmentManager.java:900)
 E / AndroidRuntime (834): en android.app.FragmentManagerImpl.addFragment (FragmentManager.java:978)
 E / AndroidRuntime (834): en android.app.Activity.onCreateView (Activity.java:4090)
 E / AndroidRuntime (834): en android.view.LayoutInflater.createViewFromTag (LayoutInflater.java:664)

Realmente debe haber algo como MapFragment que se encarga de los hilos de fondo MapView necesidades, supongo … Entonces, ¿cuál es la mejor práctica actual para hacer esto?

Gracias y saludos de Alemania, Valentin

A partir del 03.12.2012 Google lanzó Google Maps Android API v2 . Ahora puede olvidarse de estos problemas. https://developers.google.com/maps/documentation/android/

Ejemplo de uso de la nueva API: https://developers.google.com/maps/documentation/android/start#add_a_map

Esta API funcionará para al menos Android API 8, así que úsela;).

Así que ahora puedes simplemente usar la clase "com.google.android.gms.maps.MapFragment". Se mostrará el mapa en su actividad. Ejemplo de diseño del enlace anterior:

<?xml version="1.0" encoding="utf-8"?> <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.google.android.gms.maps.MapFragment"/> 

He logrado resolver esto usando TabHost en fragmento.

Aquí está la idea (brevemente):

  1. MainFragmentActivity extiende FragmentActivity (de la biblioteca de soporte) y tiene MapFragment .

  2. MyMapActivity extiende MapActivity y contiene MapView .

  3. LocalActivityManagerFragment hosts LocalActivityManager

  4. MapFragment extiende MapFragment .

  5. Y MyMapActivity contiene la actividad de MyMapActivity en ella.

Ejemplo de implementación: https://github.com/inazaruk/map-fragment .


Introduzca aquí la descripción de la imagen

Como se discutió en Google Groups , Peter Doyle creó una biblioteca de compatibilidad personalizada que también admite Google Maps. Android-support-v4-googlemaps

Sin embargo, también hay un inconveniente:

Actualmente, una desventaja es que TODAS las clases que extienden FragmentActivity son MapActivitys. Es posible hacer una clase separada (es decir, FragmentMapActivity), pero requiere una cierta refactorización del código FragmentActivity.

Sólo para aclarar la respuesta. He intentado el enfoque sugerido por inazaruk y ChristophK. En realidad, puede ejecutar cualquier actividad en un fragmento – no sólo google maps. Aquí está el código que implementa la actividad del mapa google como un fragmento gracias a inazaruk y ChristophK.

 import com.actionbarsherlock.app.SherlockFragment; import android.view.Window; import android.app.LocalActivityManager; import android.content.Intent; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class MapFragment extends SherlockFragment { private static final String KEY_STATE_BUNDLE = "localActivityManagerState"; private LocalActivityManager mLocalActivityManager; protected LocalActivityManager getLocalActivityManager() { return mLocalActivityManager; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Bundle state = null; if (savedInstanceState != null) { state = savedInstanceState.getBundle(KEY_STATE_BUNDLE); } mLocalActivityManager = new LocalActivityManager(getActivity(), true); mLocalActivityManager.dispatchCreate(state); } public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { //This is where you specify you activity class Intent i = new Intent(getActivity(), GMapActivity.class); Window w = mLocalActivityManager.startActivity("tag", i); View currentView=w.getDecorView(); currentView.setVisibility(View.VISIBLE); currentView.setFocusableInTouchMode(true); ((ViewGroup) currentView).setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); return currentView; } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putBundle(KEY_STATE_BUNDLE, mLocalActivityManager.saveInstanceState()); } @Override public void onResume() { super.onResume(); mLocalActivityManager.dispatchResume(); } @Override public void onPause() { super.onPause(); mLocalActivityManager.dispatchPause(getActivity().isFinishing()); } @Override public void onStop() { super.onStop(); mLocalActivityManager.dispatchStop(); } @Override public void onDestroy() { super.onDestroy(); mLocalActivityManager.dispatchDestroy(getActivity().isFinishing()); } } 

Buenas noticias de Google sobre esto. Lanzan hoy una nueva API de Google Maps , con mapas interiores y MapFragment.

 With this new API, adding a map to your Activity is as simple as: <fragment android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent" class="com.google.android.gms.maps.MapFragment" /> 

La API de Google Maps no forma parte del AOSP. Mientras no Googler responda, es apenas posible decir si habrá un MapFragment en el futuro.

Una posible alternativa limitada es usar un WebViewFragment y abusar de él para cargar una dirección personalizada maps.google.com .

Hm es una pena que Google no ha respondido todavía. FWIW si realmente necesitas hacer esto no encontré otra manera que:

Haga que la actividad de gestión de fichas hereda de MapActivity, cree el MapView allí programáticamente, haga que mapfragment.xml contenga un ViewGroup y agregue el MapView al ViewGroup utilizando

 (ViewGroup) getFragmentManager (). FindFragmentById (R.id.finder_map_fragment) .getView ()). AddView (mapView) ;;

Evidentemente, esto va en contra de la idea de que los fragmentos deben ser autónomos pero …

Aquí está una versión MonoDroid ( Mono para Android ) de un MapFragment muy simplificado:

 public class MapFragment : Fragment { // FOLLOW http://stackoverflow.com/questions/5109336/mapview-in-a-fragment-honeycomb private static String KEY_STATE_BUNDLE = "localActivityManagerState"; public override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); Bundle state = null; if (savedInstanceState != null) { state = savedInstanceState.GetBundle(KEY_STATE_BUNDLE); } mLocalActivityManager = new LocalActivityManager(Activity, true); mLocalActivityManager.DispatchCreate(state); } public override Android.Views.View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { //This is where you specify you activity class Intent i = new Intent(Activity, typeof(SteamLocationMapActivity)); Window w = mLocalActivityManager.StartActivity("tag", i); View currentView=w.DecorView; currentView.Visibility = ViewStates.Visible; currentView.FocusableInTouchMode = true; ((ViewGroup) currentView).DescendantFocusability = DescendantFocusability.AfterDescendants; return currentView; } private LocalActivityManager mLocalActivityManager; protected LocalActivityManager GetLocalActivityManager() { return mLocalActivityManager; } public override void OnSaveInstanceState(Bundle outState) { base.OnSaveInstanceState(outState); outState.PutBundle(KEY_STATE_BUNDLE,mLocalActivityManager.SaveInstanceState()); } public override void OnResume() { base.OnResume(); mLocalActivityManager.DispatchResume(); } public override void OnPause() { base.OnPause(); mLocalActivityManager.DispatchPause(Activity.IsFinishing); } public override void OnStop() { base.OnStop(); mLocalActivityManager.DispatchStop(); } } 

Esto soluciona mi problema al agregar MapView en Fragmentos. https://github.com/petedoyle/android-support-v4-googlemaps

Con la nueva versión de ABS 4.0, no hay soporte para MapFragmentActivity, aquí hay una buena solución para tener un mapview en un Fragmento!

https://xrigau.wordpress.com/2012/03/22/howto-actionbarsherlock-mapfragment-listfragment/#comment-21

¿Puedo obtener la solución:

  1. Create class TempFragmentActivity extiende MapActivity
  2. Hay un objeto MapView dentro de TempFragmentActivity (como normal define en xml)
  3. Quitar este objeto de formulario MapView parent (LinearLayout) (excepción void posterior)
  4. Mantener este objeto MapView en algún lugar (por ejemplo: miembro estático de TempFragmentActivity)
  5. En su Fragmento, agregue este objeto MapView usando código (no defina en xml) en algún LinearLayout

Escribí una pequeña biblioteca, mezclando las soluciones basadas en LocalActivityManager para el problema de MapFragment (también incluye una aplicación de ejemplo que muestra varias situaciones de uso):

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

  • Cambiar Google Map Offset Center
  • Ekito Simple KML leer la fuente
  • Mover marcador en google maps api 2
  • Dibuja línea suave entre geopuntos en android
  • ActionBarSherlock + ID de duplicado de la API de Google Maps v2
  • Mostrar el número total como texto para múltiples pines con un pin en la misma ubicación en el mapa en android
  • ActivityCompat.requestPermissions no muestra el mensaje
  • Dibujar la polilínea a la aplicación Android google maps
  • NullPointerException en mapFragment.getMapAsync
  • Cómo utilizar múltiples MapActivities / MapViews por aplicación / proceso de Android
  • ¿Hay alguna manera de mostrar las instrucciones de la ruta en Google Map API v2?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.