我在寻呼机内使用寻呼机和片段管理器来创建 5 个“桌面”(片段的视图)。在第 5 个桌面中,我有一张带有地理位置的地图(我使用类扩展片段并实现 LocationListener,因为我想在 android 2.2 中使用该应用程序)。我使用此类中的 onCreateView 来创建地图(我使用 switch(currentpage) 在“桌面”之间进行切换)。
当我运行应用程序时,5 个视图分别运行良好,当我在它们之间切换时(从第 1 个到第 5 个),一切运行良好。但是当我返回(并且第 5 个视图被破坏)时,当我尝试再次返回第 5 个视图时,应用程序在 v=inflater.inflate[...] 行中崩溃。
代码是这样的:
package com.example.herbalife;
import java.util.List;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
public class MyFragment extends Fragment implements LocationListener{
//Variables
int mCurrentPage;
Context ctx;
Boolean crearMapa = true;
//Controles
View v;
ListView lv;
LVTodosProductosAdaptador adapterTodosProds;
LVCarritoAdaptador adapterCarrito;
ArrayAdapter<String> miAdaptador;
//controles del mapa
LatLng coordenadasPos; //almacenar coordenadas pos actual
LocationManager miLocMgr; //manejador de localización
LocationProvider locProveedor;//almacenar cada proveedor
GoogleMap miMapa; //para inflar el fragmen del mapa
Location miLocation; //para conocer las coordenadas geoPos
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/** Getting the arguments to the Bundle object */
Bundle data = getArguments();
/** Getting integer data of the key current_page from the bundle */
mCurrentPage = data.getInt("current_page", 0);
}
//crea las vistas para cada fragmento
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
switch (mCurrentPage) { // cada case representa una vista, y cada uno lleva un inflador diferente para mostrar todos los productos
case 1:
v = inflater.inflate(R.layout.fragmentproductos_layout, container,false);
ctx=v.getContext();
//referencias a controles en la vista del fragment
lv = (ListView) v.findViewById(R.id.listView1);
//control de clicks en el listview
lv.setOnItemClickListener(new ListView.OnItemClickListener() {
@SuppressWarnings("deprecation")
@Override
public void onItemClick(AdapterView<?> adaptador, View view, int position, long idItem) {
try {
//Muestra dialog al clicar en un item del listview
getActivity().showDialog(position);
}
catch(Exception e) {
Log.e("Ciclo", e.toString());
}
}
});
// crear una instancia de nuestro adaptador al que se le pasa la fuente de datos
adapterTodosProds = new LVTodosProductosAdaptador(v.getContext(), CargaBD.misProductos);
lv.setAdapter(adapterTodosProds);
break;
//para mostrar los objetos del carrito
case 2:
v = inflater.inflate(R.layout.fragmentproductos_layout, container, false);
// referencias a controles en la vista del fragment
lv = (ListView) v.findViewById(R.id.listView1);
// crea una instancia de nuestro adaptador al que se le pasa la fuente de datos
adapterCarrito = new LVCarritoAdaptador(v.getContext(), CargaBD.miCarrito);
lv.setAdapter(adapterCarrito);
break;
//para mostrar el mapa con la geolocalizacion
case 5:
v = inflater.inflate(R.layout.activity_localizacion, container,false); //IT BREAKS HERE, WHEN REINSTANTIATING THE VIEW
ctx=v.getContext();
//Instanciar el fragmento
miMapa = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
//Definir el manajador de localización
miLocMgr=(LocationManager) ctx.getSystemService(ctx.LOCATION_SERVICE);
//Determinar que proveedor está disponible y fijar el marcador en la posición
locProveedor=obtenerProveedores();
if (locProveedor!=null){ //Si hay algún proveedor disponible
Toast.makeText(ctx, "El proveedor que se utilizará es "+ locProveedor.getName(),Toast.LENGTH_LONG).show();
//Se obtiene el objeto Location del proveedor disponible
miLocation=miLocMgr.getLastKnownLocation(locProveedor.getName());
}
else{
Toast.makeText(ctx, "No hay ningún proveedor disponible", Toast.LENGTH_LONG).show();
//Se obtiene el objeto Location del proveedor network
miLocation=miLocMgr.getLastKnownLocation("network");
}
//Si hay una Location válida
if (miLocation != null) {
// Calcular coordenadas actuales
coordenadasPos = calcularPosActual(miLocation);
// Hacer zoom y marker
zoomYMarker(miMapa, coordenadasPos);
/* se actualizará cada minuto y 5 metros de cambio en la localización
mientras más pequeños sean estos valores más frecuentes serán las actualizaciones */
/*el método requestLocation... requiere de que la clase tenga implementada la interfaz LocationListener
* Pues su último argumento es una instancia de LocationListener. */
miLocMgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 5, this);
}
}
return v;
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
switch (mCurrentPage) {
case 1:
break;
case 2:
super.setUserVisibleHint(isVisibleToUser);
if(this.isVisible()){
if(isVisibleToUser){
// crea una instancia de nuestro adaptador al que se le pasa la fuente de datos
adapterCarrito = new LVCarritoAdaptador(v.getContext(), CargaBD.miCarrito);
lv.setAdapter(adapterCarrito);
}
}
break;
}
}
@Override
public void onDestroyView() {
// TODO Auto-generated method stub
super.onDestroyView();
switch (mCurrentPage) {
case 5:
Log.e("Ciclo", "Destruye vista del mapa");
break;
}
}
/************************************* METODOS PARA USOS DEL MAPA **************************************/
//Muestra una lista de todos los porveedores
private LocationProvider obtenerProveedores() {
LocationProvider elProveedor = null;
//Obtengo la lista de proveedores actuales
List<String> proveedores = miLocMgr.getAllProviders();
//Para cada uno de los proveedores
for (String proveedor : proveedores) {
//Obtengo cada uno de los proveedores
locProveedor = miLocMgr.getProvider(proveedor);
// Si está activo el GPS y disponible
if (locProveedor.getName().equals("gps") & miLocMgr.isProviderEnabled(proveedor)) {
Log.e("Ciclo", "GPS ENABLED");
elProveedor=locProveedor;
}
else if (locProveedor.getName().equals("network") & miLocMgr.isProviderEnabled(proveedor)) { // Si está activo network
Log.e("Ciclo", "NETWORK ENABLED");
elProveedor=locProveedor;
}
}
return elProveedor;
}
//Calcula las corrdenadas actuales
private LatLng calcularPosActual(Location laLocation){
Double latitud=laLocation.getLatitude();
Double longitud=laLocation.getLongitude();
return new LatLng (latitud,longitud);
}
//Muestra la zona con unas coordenadas y dibuja un marker
private void zoomYMarker(GoogleMap elMapa, LatLng lasCoordenadas){
elMapa.moveCamera(CameraUpdateFactory.newLatLngZoom(lasCoordenadas,10));
elMapa.addMarker(new MarkerOptions()
.position(lasCoordenadas)
.title("Mi Posicion")
.snippet("Aquí estoy y me pasa esto")
.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher))
.anchor(0.5f, 0.5f));
}
//Se ejecuta cuando varía la localización en función de los datos introducidos en miLocMgr.requestLocationUpdates
@Override
public void onLocationChanged(Location location) {
// Calcular coordenadas actuales
coordenadasPos = calcularPosActual(miLocation);
miMapa.clear();
// Hacer zoom y marker
zoomYMarker(miMapa, coordenadasPos);
}
//Se ejecuta cuando se desactiva el proveedor de servicios de localización
@Override
public void onProviderDisabled(String provider) {
Toast.makeText(getActivity(), "Servicio de red de localización desactivado", Toast.LENGTH_SHORT).show();
}
//Se ejecuta cuando se activa el proveedor de servicios de localización
@Override
public void onProviderEnabled(String provider) {
Toast.makeText(getActivity(), "Servicio de red de localización activado", Toast.LENGTH_SHORT).show();
}
//Este método debería ejecutarse cuando cambia el estado del proveedor de servicio
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
//status contiene constantes que identifican el estado del servicio
Toast.makeText(getActivity(), "El estado de la red ha cambiado", Toast.LENGTH_SHORT).show();
}
}
我收到此错误:
03-21 20:59:37.080: E/AndroidRuntime(2022): FATAL EXCEPTION: main
03-21 20:59:37.080: E/AndroidRuntime(2022): android.view.InflateException: Binary XML file line #11: Error inflating class fragment
03-21 20:59:37.080: E/AndroidRuntime(2022): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:582)
03-21 20:59:37.080: E/AndroidRuntime(2022): at android.view.LayoutInflater.rInflate(LayoutInflater.java:618)
03-21 20:59:37.080: E/AndroidRuntime(2022): at android.view.LayoutInflater.inflate(LayoutInflater.java:407)
03-21 20:59:37.080: E/AndroidRuntime(2022): at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
03-21 20:59:37.080: E/AndroidRuntime(2022): at com.example.herbalife.MyFragment.onCreateView(MyFragment.java:108)
03-21 20:59:37.080: E/AndroidRuntime(2022): at android.support.v4.app.Fragment.performCreateView(Fragment.java:1460)
03-21 20:59:37.080: E/AndroidRuntime(2022): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:911)
03-21 20:59:37.080: E/AndroidRuntime(2022): at android.support.v4.app.FragmentManagerImpl.attachFragment(FragmentManager.java:1264)
03-21 20:59:37.080: E/AndroidRuntime(2022): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:672)
03-21 20:59:37.080: E/AndroidRuntime(2022): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444)
03-21 20:59:37.080: E/AndroidRuntime(2022): at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:461)
03-21 20:59:37.080: E/AndroidRuntime(2022): at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
03-21 20:59:37.080: E/AndroidRuntime(2022): at android.support.v4.view.ViewPager.populate(ViewPager.java:1012)
03-21 20:59:37.080: E/AndroidRuntime(2022): at android.support.v4.view.ViewPager.populate(ViewPager.java:881)
03-21 20:59:37.080: E/AndroidRuntime(2022): at android.support.v4.view.ViewPager$3.run(ViewPager.java:237)
03-21 20:59:37.080: E/AndroidRuntime(2022): at android.os.Handler.handleCallback(Handler.java:587)
03-21 20:59:37.080: E/AndroidRuntime(2022): at android.os.Handler.dispatchMessage(Handler.java:92)
03-21 20:59:37.080: E/AndroidRuntime(2022): at android.os.Looper.loop(Looper.java:143)
03-21 20:59:37.080: E/AndroidRuntime(2022): at android.app.ActivityThread.main(ActivityThread.java:4914)
03-21 20:59:37.080: E/AndroidRuntime(2022): at java.lang.reflect.Method.invokeNative(Native Method)
03-21 20:59:37.080: E/AndroidRuntime(2022): at java.lang.reflect.Method.invoke(Method.java:521)
03-21 20:59:37.080: E/AndroidRuntime(2022): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
03-21 20:59:37.080: E/AndroidRuntime(2022): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
03-21 20:59:37.080: E/AndroidRuntime(2022): at dalvik.system.NativeStart.main(Native Method)
03-21 20:59:37.080: E/AndroidRuntime(2022): Caused by: java.lang.IllegalArgumentException: Binary XML file line #11: Duplicate id 0x7f040005, tag null, or parent id 0x0 with another fragment for com.google.android.gms.maps.SupportMapFragment
03-21 20:59:37.080: E/AndroidRuntime(2022): at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:285)
03-21 20:59:37.080: E/AndroidRuntime(2022): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:558)
03-21 20:59:37.080: E/AndroidRuntime(2022): ... 23 more