0

我在寻呼机内使用寻呼机和片段管理器来创建 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
4

1 回答 1

0

你检查过每张地图是否有不同的ID吗?我有这个问题,正在寻找解决这个问题的方法,我找到了你的问题。我CustomFragmentMap的 id 与我的com.google.android.gms.maps.SupportMapFragment检查相同 ActivityView 中的每个 id 都不同。

于 2013-05-03T10:46:18.937 回答