Ahora que el SDK final está disponible con las API de Google, ¿cuál es la mejor manera de crear un Fragmento con MapView? MapView necesita MapActivity para funcionar correctamente.
Tener la actividad que administra los fragmentos heredada de MapActivity (mala solución porque va en contra de la idea de que los fragmentos son autónomos) y usar un diseño regular basado en xml no funciona. Obtengo 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 MapView mediante programación 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 solo 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 debería haber algo como MapFragment que se encargue de los subprocesos de fondo que necesita MapView, supongo ... Entonces, ¿cuál es la mejor práctica actual para hacer esto?
Gracias y saludos desde Alemania, Valentin
Respuestas:
A partir del 03.12.2012, Google lanzó Google Maps Android API v2 . Ahora puedes olvidarte de estos problemas. https://developers.google.com/maps/documentation/android/
Ejemplo usando una nueva API: https://developers.google.com/maps/documentation/android/start#add_a_map
Esta API funcionará al menos para la API 8 de Android, así que úsala;).
Así que ahora puede simplemente usar la clase de fragmento "com.google.android.gms.maps.MapFragment". Mostrará el mapa en su Actividad. Ejemplo de diseño del enlace de arriba:
<?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"/>
fuente
Me las arreglé para resolver esto usando TabHost en fragmento.
Aquí está la idea (brevemente):
MainFragmentActivity
extiendeFragmentActivity
(de la biblioteca de soporte) y tieneMapFragment
.MyMapActivity
extiendeMapActivity
y contieneMapView
.LocalActivityManagerFragment
HospedadoresLocalActivityManager
MapFragment
se extiendeLocalActivityManagerFragment
.Y
LocalActivityManager
contieneMyMapActivity
actividad en él.Implementación de ejemplo: https://github.com/inazaruk/map-fragment .
fuente
Intent i = new Intent(getActivity().getParent(), MyMapActivity.class); Window w = localActivityManager.startActivity("tag", i); currentView=w.getDecorView(); currentView.setVisibility(View.VISIBLE); currentView.setFocusableInTouchMode(true); ((ViewGroup) currentView).setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); this.contentView.addView(currentView);
LocalActivityManager
está desaprobado, pero esto es solo un truco, este problema se resolverá adecuadamente cuando decidan incluir el soporte adecuado para Mapas dentro de Fragmentos.Como se discutió en Google Groups , Peter Doyle construyó una biblioteca de compatibilidad personalizada que también admite Google Maps. android-support-v4-googlemaps
Sin embargo, también hay una desventaja:
fuente
Solo para aclarar la respuesta. Probé el enfoque sugerido por inazaruk y ChristophK. En realidad, puede ejecutar cualquier actividad en un fragmento, no solo Google Maps. Aquí está el código que implementa la actividad del mapa de 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()); } }
fuente
LocalActivityManager
(como se comenta aquí: code.google.com/p/android/issues/detail?id=15347 ) implica extender todoFragmentActivities
, lo que parece aún menos óptimo.Buenas noticias de Google sobre esto. Hoy están lanzando una nueva API de Google Maps , con mapas de 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" />
fuente
La API de Google Maps no forma parte del AOSP. Mientras ningún Googler responda, apenas es posible saber si habrá un MapFragment en el futuro.
Una posible alternativa limitada es usar
WebViewFragment
y abusar de él para cargar unamaps.google.com
URL personalizada .fuente
Lástima que Google no haya respondido todavía. FWIW si realmente necesitas hacer esto, no encontré otra manera que:
Haga que la actividad de gestión de pestañas herede de MapActivity, cree MapView allí mediante programación, haga que mapfragment.xml contenga un ViewGroup y agregue MapView al ViewGroup
Claramente, esto va fuertemente en contra de la idea de que los fragmentos deben ser autónomos pero ...
fuente
Aquí hay 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(); } }
fuente
Esto resuelve mi problema al agregar MapView en fragmentos. https://github.com/petedoyle/android-support-v4-googlemaps
fuente
Con la nueva versión de ABS 4.0, no hay soporte para MapFragmentActivity, ¡aquí hay una buena solución para tener una vista de mapa en un Fragmento!
https://xrigau.wordpress.com/2012/03/22/howto-actionbarsherlock-mapfragment-listfragment/#comment-21
fuente
¿Puedo obtener la solución?
fuente
Escribí una pequeña biblioteca, combinando 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
fuente