GoogleMaps dentro de un Fragment

6,354 views
Skip to first unread message

Jefferson Delgado P.

unread,
Jul 31, 2013, 12:21:45 PM7/31/13
to desarrollad...@googlegroups.com
Buenas a todos,

Llevo bastante rato peleándome, para poder hacer lo que pretendo. Me explico para que me entiendan.

Tengo un SlideMenú estilo Facebook, con 4 botones, y cada botón carga en el panel de la derecha, un apartado.
La sustitución de cada elemento lo hago mediante FragmentTransaction y replace.
3 de los botones no tengo problema, ya que las clases que carga extienden de Fragment y sin problema.

El problema viene con uno de ellos, que tengo que mostrar el mapa de google, y el único modo que he conseguido, tras probar bastantes, ha sido el siguiente:

public class FragmentMapa extends android.support.v4.app.FragmentActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.mapa);
    }
}

<?xml version="1.0" encoding="utf-8"?>
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.google.android.gms.maps.SupportMapFragment"/>


He intentado que la clase FragmentMapa extienda de Fragment, he pueso el código y demás peero cuando ejecuto, me da un error en el xml, tal que así:

android.view.InflateException: Binary XML file line #2: Error inflating class fragment
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
at android.view.LayoutInflater.inflate(LayoutInflater.java:466)
at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
at com.ejemplo.pruebamapa.FragmentMapa.onCreateView(FragmentMapa.java:14)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:831)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1015)
at android.app.Activity.onCreateView(Activity.java:4741)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:680)
at android.view.LayoutInflater.inflate(LayoutInflater.java:466)
at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
at com.singularfactory.LivingApp.FragmentMapa.onCreateView(FragmentMapa.java:14)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:831)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1037)
at android.app.BackStackRecord.run(BackStackRecord.java:635)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1399)
at android.app.FragmentManagerImpl$1.run(FragmentManager.java:428)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:155)
at android.app.ActivityThread.main(ActivityThread.java:5520)
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:1029)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:796)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalArgumentException: Binary XML file line #2: Duplicate id 0x7f050033, tag null, or parent id 0x7f05000f with another fragment for com.google.android.gms.maps.SupportMapFragment
at android.app.Activity.onCreateView(Activity.java:4727)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:680)
... 24 more


He probado a meter el fragment del mapa dentro de un RelativeLayout y también me ha dado error.

¿Alguna idea de como podría hacerse?


Muchas gracias.


Un saludo




Juan de Dios Maldonado Sánchez

unread,
Jul 31, 2013, 12:31:05 PM7/31/13
to desarrollad...@googlegroups.com
Si buscas en Google:

Caused by: java.lang.IllegalArgumentException: Binary XML file line #2: Duplicate id , tag null, or parent id with another fragment for com.google.android.gms.maps.SupportMapFragment

Tienes soluciones a "cascoporro".



2013/7/31 Jefferson Delgado P. <jjde...@gmail.com>




--
Para participar es necesario que leas detenidamente las normas del grupo: http://goo.gl/20KhL
---
Has recibido este mensaje porque estás suscrito al grupo "desarrolladores-android" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus correos electrónicos, envía un correo electrónico a desarrolladores-a...@googlegroups.com.
Para publicar una entrada en este grupo, envía un correo electrónico a desarrollad...@googlegroups.com.
Visita este grupo en http://groups.google.com/group/desarrolladores-android.
Para ver este debate en la Web, visita https://groups.google.com/d/msgid/desarrolladores-android/9d25efdc-1913-4f7c-a476-5974bf8dc9ef%40googlegroups.com.
Para obtener más opciones, visita https://groups.google.com/groups/opt_out.
 
 

Jorge Luis Ortiz Castillo

unread,
Jul 31, 2013, 12:33:05 PM7/31/13
to desarrollad...@googlegroups.com
Hola aqui te dejo el código que a mi me funciona correctamente.

En el AndroidManifest tenemos configurado lo siguiente:

<permission android:name="<tu package>.permission.MAPS_RECEIVE"
        android:protectionLevel="signature"/>
    
    <uses-permission android:name="<tu package>.permission.MAPS_RECEIVE"/>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
    <uses-feature android:glEsVersion="0x00020000" android:required="true"/>

<uses-library android:required="true" android:name="com.google.android.maps"/>
       
        <meta-data android:name="com.google.android.maps.v2.API_KEY"
            android:value="<TU API KEY GENERADA>"/>


En el layout esto:

<?xml version="1.0" encoding="utf-8"?>
        android:id="@+id/map"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        class="com.google.android.gms.maps.SupportMapFragment"/>

y en la activity esto:

import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;

public class MapaActivity extends android.support.v4.app.FragmentActivity{
private GoogleMap mapa;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mapa);
mapa = ((SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
}
}

Espero te sirva estimado.

Saludos.

Jefferson Delgado P.

unread,
Aug 1, 2013, 5:06:58 AM8/1/13
to desarrollad...@googlegroups.com
Buenas nuevamente,

Muchas gracias Jorge por el código. Así lo tengo yo y así me funciona, pero necesito que la clase MapaActivity extienda de Fragment, para poder jugar con el tema de replace y demás.

Juan, gracias por la respuesta. He estado mirando y casi todos los ejemplos que he visto, extienden la clase de FragmentActivity, y por lo poco que entiendo, la clase debe extender de Fragment para poder usar FragmentManager y FragmentTransaction.

¿Me podrías echar un cable?


Muchas gracias nuevamente.

Un saludo


--
Para participar es necesario que leas detenidamente las normas del grupo: http://goo.gl/20KhL
---
Has recibido este mensaje porque estás suscrito al grupo "desarrolladores-android" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus correos electrónicos, envía un correo electrónico a desarrolladores-a...@googlegroups.com.
Para publicar una entrada en este grupo, envía un correo electrónico a desarrollad...@googlegroups.com.
Visita este grupo en http://groups.google.com/group/desarrolladores-android.

Gabriel Pozo

unread,
Aug 1, 2013, 9:02:48 AM8/1/13
to desarrollad...@googlegroups.com

Jefferson Delgado P.

unread,
Aug 1, 2013, 9:58:52 AM8/1/13
to desarrollad...@googlegroups.com
Gracias por la respuesta Gabriel,

Gracias a tu enlace, encontré otro en el cual indicaban un código que al parecer, hace lo que se pide. Por tanto, mi clase queda del siguiente modo:

public class FragmentMapa extends Fragment {
private static View view;
 
public FragmentMapa(){
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
   if (view != null) {
       ViewGroup parent = (ViewGroup) view.getParent();
       if (parent != null)
           parent.removeView(view);
   }
   try {
       view = inflater.inflate(R.layout.mapa, container, false);
   } catch (InflateException e) {
       /* map is already there, just return view as it is */
   }
   return view;
}
@Override
    public void onDestroyView() {
        super.onDestroyView();
        MapFragment f = (MapFragment) getFragmentManager().findFragmentById(R.id.mapFragment);
        if (f != null) 
            getFragmentManager().beginTransaction().remove(f).commit();
    }
}

Y el xml tal que asi:

Introducir código aquí...<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mapLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <fragment
        android:id="@+id/mapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.google.android.gms.maps.SupportMapFragment" />
</LinearLayout>

Ya no me da ningún error al cargar el Fragment; el problema ahora es que no me carga el mapa, lo deja en blanco :S

¿Alguna idea de por qué?

Gracias nuevamente.


Un saludo!

Gabriel Pozo

unread,
Aug 1, 2013, 10:05:02 AM8/1/13
to desarrollad...@googlegroups.com
Un par de cosas, simplemente busque la respuesta y creo que fue la primera, de la linea:
Caused by: java.lang.IllegalArgumentException: Binary XML file line #2: Duplicate id 0x7f050033, tag null, or parent id 0x7f05000f with another fragment for com.google.android.gms.maps.SupportMapFragment

Que fue lo mismo que te indico Juan ;)


Ahora lo que decís, no podrá ser por el API Key?




--
Para participar es necesario que leas detenidamente las normas del grupo: http://goo.gl/20KhL
---
Has recibido este mensaje porque estás suscrito al grupo "desarrolladores-android" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus correos electrónicos, envía un correo electrónico a desarrolladores-a...@googlegroups.com.
Para publicar una entrada en este grupo, envía un correo electrónico a desarrollad...@googlegroups.com.
Visita este grupo en http://groups.google.com/group/desarrolladores-android.

Para obtener más opciones, visita https://groups.google.com/groups/opt_out.
 
 

Jefferson Delgado P.

unread,
Aug 1, 2013, 10:11:44 AM8/1/13
to desarrollad...@googlegroups.com
Cierto, fue la primera que me indicó Juan, pero se ve que la pasé por alto :$

No creo que sea el API Key, ya que probé el mapa antes de meterlo en un Fragment y me funcionó correctamente, me mostró el mapa sin problemas.

Disculpa Juan mi despiste con la ayuda que me ofreciste y que yo no supe ver :)


Gabriel Pozo

unread,
Aug 1, 2013, 10:48:16 AM8/1/13
to desarrollad...@googlegroups.com
Y el log que muestra?



Para obtener más opciones, visita https://groups.google.com/groups/opt_out.
 
 

Jefferson Delgado P.

unread,
Aug 1, 2013, 12:32:38 PM8/1/13
to desarrollad...@googlegroups.com
Pues eso es lo extraño Gabriel, el log se queda en blanco, igual que la pantalla. "Carga" al layout correspondiente pero no se ve el mapa.

Si te es de ayuda, pongo más codigo.


Un saludo


El miércoles, 31 de julio de 2013 17:21:45 UTC+1, Jefferson Delgado P. escribió:

Jefferson Delgado P.

unread,
Aug 2, 2013, 6:09:18 AM8/2/13
to desarrollad...@googlegroups.com
¿Alguna idea o teoría de por qué no me carga el mapa en el Fragment, cuando antes si me lo cargaba en un activity normal y corriente?

Un saludo


--
Para participar es necesario que leas detenidamente las normas del grupo: http://goo.gl/20KhL
---
Has recibido este mensaje porque estás suscrito al grupo "desarrolladores-android" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus correos electrónicos, envía un correo electrónico a desarrolladores-a...@googlegroups.com.
Para publicar una entrada en este grupo, envía un correo electrónico a desarrollad...@googlegroups.com.
Visita este grupo en http://groups.google.com/group/desarrolladores-android.

Juan de Dios Maldonado Sánchez

unread,
Aug 2, 2013, 6:58:31 AM8/2/13
to desarrollad...@googlegroups.com

Jefferson Delgado P.

unread,
Aug 2, 2013, 12:13:22 PM8/2/13
to desarrollad...@googlegroups.com
Gracias por el enlace Juan,

Tras seguir rebuscando, he conseguido que me muestre el mapa en el Fragment sin problemas.
El código que he usado, es el siguiente (tiene algún añadido para el uso del mapa):

Introducir códigopublic class FragmentMapa extends Fragment {

private MapView mMapView;
private GoogleMap mMap;
private Bundle mBundle;

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

try {
MapsInitializer.initialize(getActivity());
} catch (GooglePlayServicesNotAvailableException e) {
// TODO handle this situation
}

mMapView = (MapView) inflatedView.findViewById(R.id.map);
mMapView.onCreate(mBundle);
setUpMapIfNeeded(inflatedView);

return inflatedView;
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBundle = savedInstanceState;
}

private void setUpMapIfNeeded(View inflatedView) {
if (mMap == null) {
mMap = ((MapView) inflatedView.findViewById(R.id.map)).getMap();
if (mMap != null) {
setUpMap();
}
}
}

private void setUpMap() {
mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}

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

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

@Override
public void onDestroy() {
mMapView.onDestroy();
super.onDestroy();
}
} aquí...

Y el XML:

Introducir código aquí...<?xml version="1.0" encoding="utf-8"?>
<com.google.android.gms.maps.MapView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/map"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" />


Lo único extraño que veo, es que antes de mostrar el mapa, por un milisegundo, muestra el layout totalmente negro, para a continuación cargar el mapa.
¿Alguna idea de por qué ocurre esto?


Muchas gracias nuevamente, sois una fuente de sabiduría importante :)


Un saludo






El miércoles, 31 de julio de 2013 17:21:45 UTC+1, Jefferson Delgado P. escribió:

Juan de Dios Maldonado Sánchez

unread,
Aug 2, 2013, 12:22:53 PM8/2/13
to desarrollad...@googlegroups.com
Aquí hablan de un problema similar y casi al final del todo ponen el enlace a una librería que soluciona el problema del fondo negro cuando se carga el mapa. (O al menos eso dicen en un comentario posterior)

https://code.google.com/p/gmaps-api-issues/issues/detail?id=4639

Me alegro que hayas podido solucionar tu problema.


2013/8/2 Jefferson Delgado P. <jjde...@gmail.com>
Gracias por el enlace Juan,

--
Para participar es necesario que leas detenidamente las normas del grupo: http://goo.gl/20KhL
---
Has recibido este mensaje porque estás suscrito al grupo "desarrolladores-android" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus correos electrónicos, envía un correo electrónico a desarrolladores-a...@googlegroups.com.
Para publicar una entrada en este grupo, envía un correo electrónico a desarrollad...@googlegroups.com.
Visita este grupo en http://groups.google.com/group/desarrolladores-android.

Jefferson Delgado P.

unread,
Aug 2, 2013, 12:30:21 PM8/2/13
to desarrollad...@googlegroups.com
Según leo en los comentarios, indican que se soluciona el problema de la pantalla negra cuando se inicializa el mapa, pero que si juegas con el y demás, vuelve a aparecer la pantalla negra.

Seguiré investigando ya que por ahí tienen que andar los tiros.

Muchas gracias :)


Jefferson Delgado P.

unread,
Aug 2, 2013, 1:58:20 PM8/2/13
to desarrollad...@googlegroups.com
He estado leyendo bastantes post, y la librería que proponen o las soluciones que proponen, son todos para cuando la clase extiende de SupportMapFragment, y mi clase extiende de Fragment.

He intentado adaptarlo a mis necesidades pero no he conseguido hacerlo.


Un saludo

William Andres

unread,
Aug 22, 2013, 12:42:37 AM8/22/13
to desarrollad...@googlegroups.com
Y ya has encoontrado la solución, estuve leyendo tu problemática varias veces, pero no entiendo porué nesesaria mente para mostrar tu mapa debe la actividad heredar de Fragment, disculpa si es algo fácil y yo no lo entiendo...

Jefferson Delgado P.

unread,
Aug 22, 2013, 4:22:50 AM8/22/13
to desarrollad...@googlegroups.com
Buenas William,

Debe heredar de Fragment, porque donde muestro dicho mapa es en un FrameLayout, y para poder hacer el juego de quito una vista, pongo otra, etc., necesito que las clases hereden de Fragment.

Un saludo


El 22 de agosto de 2013 05:42, William Andres <willi...@gmail.com> escribió:
Y ya has encoontrado la solución, estuve leyendo tu problemática varias veces, pero no entiendo porué nesesaria mente para mostrar tu mapa debe la actividad heredar de Fragment, disculpa si es algo fácil y yo no lo entiendo...

--
Para participar es necesario que leas detenidamente las normas del grupo: http://goo.gl/20KhL
---
Has recibido este mensaje porque estás suscrito al grupo "desarrolladores-android" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus correos electrónicos, envía un correo electrónico a desarrolladores-a...@googlegroups.com.
Para publicar una entrada en este grupo, envía un correo electrónico a desarrollad...@googlegroups.com.
Visita este grupo en http://groups.google.com/group/desarrolladores-android.

Jefferson Delgado P.

unread,
Aug 22, 2013, 6:41:20 AM8/22/13
to desarrollad...@googlegroups.com
Una pregunta,

¿Alguno se explica porqué el marker que situo en la localización actual, está en distinta posición que me coloca el mapa con mMap.setMyLocationEnabled(true);?

El código que uso es el siguiente:

private void setUpMap() {
mMap.setMyLocationEnabled(true);
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
comenzarLocalizacion();
mMap.addMarker(new MarkerOptions().position(new LatLng(latitude,longitude)).icon(BitmapDescriptorFactory.fromResource(R.drawable.localizador)).title("Marcador").draggable(true));
CameraUpdate camUpd1 = CameraUpdateFactory.newLatLngZoom(new LatLng(latitude,longitude), 18);
mMap.animateCamera(camUpd1);

}

private void comenzarLocalizacion() {

locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, false);
Location location = locationManager.getLastKnownLocation(provider);

if (location != null) {
System.out.println("Provider " + provider + " has been selected.");
onLocationChanged(location);
}
}

public void onLocationChanged(Location location) {
   latitude = location.getLatitude();
   longitude = location.getLongitude();
}


Espero que alguno pueda ayudarme, ya que llevo un gran rato intentando averiguar por qué, y no consigo averiguarlo.

Muchas gracias.


Un saludo

Jefferson Delgado P.

unread,
Aug 30, 2013, 11:44:43 AM8/30/13
to desarrollad...@googlegroups.com
Bueno, he conseguido arreglar mi problema, buscando otro LocationManager que esta vez, si parece que funciona. El código es el siguiente:

private void comenzarLocalizacion() {
LocationManager locationManager;
String context = Context.LOCATION_SERVICE;
locationManager = (LocationManager) getSystemService(context);

Criteria crta = new Criteria();
crta.setAccuracy(Criteria.ACCURACY_FINE);
crta.setAltitudeRequired(false);
crta.setBearingRequired(false);
crta.setCostAllowed(true);
crta.setPowerRequirement(Criteria.POWER_LOW);
String provider = locationManager.getBestProvider(crta, true);

Location location = locationManager.getLastKnownLocation(provider);
updateWithNewLocation(location);

locationManager.requestLocationUpdates(provider, 1000, 0,
locationListener);
}

private final LocationListener locationListener = new LocationListener() {

@Override
public void onLocationChanged(Location location) {
updateWithNewLocation(location);
}

@Override
public void onProviderDisabled(String provider) {
updateWithNewLocation(null);
}

@Override
public void onProviderEnabled(String provider) {
}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
};

private void updateWithNewLocation(Location location) {

if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();

Log.e("LOCATION", "your Current Position is :\n" + latitude + "\n "+ longitude);
}
}


Espero que le sirva a alguien.


Un saludo!

Gabriel Pozo

unread,
Aug 30, 2013, 12:17:45 PM8/30/13
to desarrollad...@googlegroups.com
Que bueno que lo hayas solucionado ;)  gracias por colocar tu solución.



Para obtener más opciones, visita https://groups.google.com/groups/opt_out.

Ignacio Rubio G

unread,
Apr 9, 2014, 10:05:18 AM4/9/14
to desarrollad...@googlegroups.com
Hola Jefferson, ha pasado casi un año desde que estabas con este código, pero me gustaría preguntarte una cosa:
¿encontraste alguna solución al "flickeo" de pantalla negra al cargar el mapa?

A mi también me ocurre...
Para anular la suscripción a este grupo y dejar de recibir sus correos electrónicos, envía un correo electrónico a desarrolladores-android+unsub...@googlegroups.com.

Para publicar una entrada en este grupo, envía un correo electrónico a desarrollad...@googlegroups.com.
Visita este grupo en http://groups.google.com/group/desarrolladores-android.

--
Para participar es necesario que leas detenidamente las normas del grupo: http://goo.gl/20KhL
---
Has recibido este mensaje porque estás suscrito al grupo "desarrolladores-android" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus correos electrónicos, envía un correo electrónico a desarrolladores-android+unsub...@googlegroups.com.

Para publicar una entrada en este grupo, envía un correo electrónico a desarrollad...@googlegroups.com.
Visita este grupo en http://groups.google.com/group/desarrolladores-android.
Reply all
Reply to author
Forward
0 new messages