Android Fragment: заменете Crash и Hide/show не работи

Създавам приложение, което прилага това плъзгащо се меню и съм доста доволен от внедряването. Разделих приложението си на няколко Fragment за едно Activity, така че за всеки раздел от менюто има Fragment. Въпросът е, че имам OnItemClickListener, който ми позволява да превключвам между Fragments, така че опитах два метода:

  1. replace() : работи добре за всички фрагменти, с изключение на един от тях, който зарежда XML, който съдържа карта (code below). При първото зареждане няма проблем, но когато превключа към друг фрагмент и се върна към този с картата, приложението се срива.

    <fragment
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.google.android.gms.maps.SupportMapFragment" />
    
    <RelativeLayout
        android:id="@+id/RelativeLayout1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
    
        <ImageButton
            android:id="@+id/refreshButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:layout_marginTop="63dp"
            android:src="@drawable/refresh"
            android:text="Rafraichir" />
    
    </RelativeLayout>
    

    public class MapFragment extends Fragment implements OnInfoWindowClickListener, LocationListener {

    private GoogleMap gMap;
    Geocoder geocoder;
    
    private LocationManager locationManager;
    private Location userLocation;
    private String provider;
    
    private ImageButton refreshButton;
    ArrayList<Parking> Parkings;
    
    Context context;
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        final View view = inflater.inflate(R.layout.fragmen_map,
                container, false);
    
        gMap = ((SupportMapFragment) getFragmentManager().findFragmentById(
                R.id.map)).getMap();
        gMap.setOnInfoWindowClickListener(this);
    
        context = getActivity();
        geocoder = new Geocoder(context);
    
        refreshButton = (ImageButton) view.findViewById(R.id.refreshButton);
        refreshButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
    
                getParkingsConnection = new GetParkingsConnection(context);
                getParkingsConnection.execute(null, null, null);
                myParkings = new ArrayList<Parking>();
            }
        });
    
        // Geolocaliation
    
        LocationManager service = (LocationManager) getActivity()
                .getSystemService(getActivity().LOCATION_SERVICE);
        boolean enabled = service
                .isProviderEnabled(LocationManager.GPS_PROVIDER);
    
        // Check if enabled and if not send user to the GSP settings
        // Better solution would be to display a dialog and suggesting to
        // go to the settings
        if (!enabled) {
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(intent);
        }
    
        // Get the location manager
        locationManager = (LocationManager) getActivity().getSystemService(
                getActivity().LOCATION_SERVICE);
        // Define the criteria how to select the locatioin provider -> use
        // default
        Criteria criteria = new Criteria();
        provider = locationManager.getBestProvider(criteria, false);
        Location location = locationManager.getLastKnownLocation(provider);
    
        return view;
    }
    
    private Double[] getLatAndLong(String addresse) {
        List<Address> addresses = null;
        Double latALng[] = new Double[2];
        try {
            addresses = geocoder.getFromLocationName(addresse, 1);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        if (addresses.size() > 0) {
            double latitude = addresses.get(0).getLatitude();
            double longitude = addresses.get(0).getLongitude();
            latALng[0] = latitude;
            latALng[1] = longitude;
        }
    
        return latALng;
    }
    
    private GetParkingsConnection getParkingsConnection;
    JSONObject json;
    
    // Non-Statice inner class : connection au serveur
    private class GetParkingsConnection extends AsyncTask<String, Void, String> {
    
        Context mContext;
        private ProgressDialog mDialog;
    
        GetParkingsConnection(Context context) {
            mContext = context;
        }
    
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
    
            mDialog = new ProgressDialog(mContext);
            mDialog.setMessage("Mise à jour de la carte...");
            mDialog.show();
        }
    
        @Override
        protected String doInBackground(String... urls) {
    
            String resultat;
            resultat = getParkings();
            return resultat;
        }
    
        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
    
            Log.d("JSON", result);
    
            JSONArray jArray;
            try {
                json = new JSONObject(result);
                jArray = json.getJSONArray("parking");
    
                System.out.println("*****Parkings*****" + jArray.length());
                for (int i = 0; i < jArray.length(); i++) {
    
                    JSONObject json_data = jArray.getJSONObject(i);
                    Log.d("adresse :",
                            json_data.getString("adresse") + ", nom :"
                                    + json_data.getString("nom")
                                    + ", latitude :"
                                    + json_data.getDouble("latitude")
                                    + ", longitude :"
                                    + json_data.getDouble("longitude"));
    
                    String adresse = json_data.getString("adresse");
                    Double latALng[] = getLatAndLong(adresse);
    
                    Double lat = latALng[0]; // json_data.getDouble("latitude");
                    Double lng = latALng[1]; // json_data.getDouble("longitude");
    
                    String nom = json_data.getString("nom");
                    LatLng parkingLocation = new LatLng(lat, lng);
    
                    Marker parking = gMap.addMarker(new MarkerOptions()
                            .position(parkingLocation)
                            .title(nom)
                            .snippet(adresse)
                            .icon(BitmapDescriptorFactory
                                    .fromResource(R.drawable.my_marker)));
    
                    Parking park = new Parking(parking.getId(), adresse, nom,
                            "", lat, lng);
                    myParkings.add(park);
                }
    
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
            mDialog.dismiss();
        }
    
        // Fonction effectuant uenrequête de type GET sur le fichier
        // getParking.php
        protected String getParkings() {
            HttpResponse response = null;
            String res = "";
            try {
                HttpClient client = new DefaultHttpClient();
                HttpGet request = new HttpGet();
                // request.setURI(new
                // URI("http://pkdom.1x.biz/getParkings.php"));
                request.setURI(new URI(
                        "http://glennsonna.fr/webService/getParkings"));
                response = client.execute(request);
                HttpEntity entity = response.getEntity();
                // JSONObject json = new JSONObject();
    
                res = EntityUtils.toString(entity);
    
            } catch (URISyntaxException e) {
                e.printStackTrace();
            } catch (ClientProtocolException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return res;
        }
    
    }
    
    @Override
    public void onInfoWindowClick(Marker marker) {
        // TODO Auto-generated method stub
    
        Parking parkingToSend = null;
    
        // TOAST
    
        /*
         * int p = 0;
         * 
         * while(myParkings.get(p).idMarker != marker.getId() && p <
         * myParkings.size()){ Log.d("Marker :" + marker.getId(),
         * myParkings.get(p).idMarker);
         * 
         * if(myParkings.get(p).idMarker.equals(marker.getId()) ){
         * parkingToSend = myParkings.get(p); Context context =
         * getApplicationContext(); CharSequence text = "Match" +
         * parkingToSend.adresse; int duration = Toast.LENGTH_SHORT; Toast toast
         * = Toast.makeText(context, text, duration); toast.show(); }
         * 
         * p++; }
         */
    
        for (int p = 0; p < myParkings.size(); p++) {
    
            Log.d("Marker :" + marker.getId(), myParkings.get(p).idMarker);
            if (myParkings.get(p).idMarker.equals(marker.getId())) {
                parkingToSend = myParkings.get(p);
    
            }
        }
    
        if (parkingToSend != null) {
            Intent i = new Intent(context.getApplicationContext(),
                    ParkingDetail.class);
            i.putExtra("id", parkingToSend.idMarker);
            i.putExtra("adresse", parkingToSend.adresse);
            i.putExtra("nom", parkingToSend.nom);
            i.putExtra("descri", parkingToSend.description);
            i.putExtra("latitude", parkingToSend.lat);
            i.putExtra("longitude", parkingToSend.lng);
            startActivity(i);
        }
    
    }
    
    @Override
    public void onLocationChanged(Location user) {
        // TODO Auto-generated method stub
    
        Log.d("Latitude", ":" + user.getLatitude());
        Log.d("Longitude", ":" + user.getLongitude());
        this.gMap.setMyLocationEnabled(true);
    
    }
    
    @Override
    public void onProviderDisabled(String provider) {
        // TODO Auto-generated method stub
    
    }
    
    @Override
    public void onProviderEnabled(String provider) {
        // TODO Auto-generated method stub
    
    }
    
    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        // TODO Auto-generated method stub
    
    }
    

    }

  2. hide() & show() : Мога да превключвам между фрагменти, но с изключение на първия екран (картата), всички останали показват празен екран без съдържание.

    лично MenuDrawer mMenuDrawer; частен MenuAdapter mAdapter; частен ListView mList; частна GoogleMap gMap;

    private int mActivePosition = -1;
    
    List<Object> mmyFragment;
    Fragment currentFragment;
    
    myMapFragment mmyMapFragment;
    myMonCompteFragment mmyMonCompteFragment;
    myPaiementFragment mmyPaiementFragment;
    myReservationsFragment mmyReservationsFragment;
    myFavorisFragment mmyFavorisFragment;
    myCodePromoFragment mmyCodePromoFragment;
    myAboutFragment mmyAboutFragment;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // setContentView(R.layout.activity_my_map);
    
        ActionBar actionBar = this.getActionBar();
        actionBar.setSubtitle("Trouvez votre parking");
        actionBar.setTitle("my");
        actionBar.setDisplayHomeAsUpEnabled(true);
    
        setupMenu();
        setupFragments();
    
    }
    
    private void setupMenu() {
    
        mMenuDrawer = MenuDrawer.attach(this, Position.LEFT);
        mMenuDrawer.setContentView(R.layout.activity_my_map);
    
        List<Object> items = new ArrayList<Object>();
        items.add(new Item("Carte", R.drawable.ic_action_refresh_dark));
        items.add(new Item("Mon Compte", R.drawable.ic_action_refresh_dark));
        items.add(new Item("Paiement", R.drawable.ic_action_select_all_dark));
        items.add(new Item("Mes Réservations",
                R.drawable.ic_action_select_all_dark));
        items.add(new Item("Mes favoris", R.drawable.ic_action_refresh_dark));
        // items.add(new Category(" "));
        items.add(new Item("Code Promo", R.drawable.ic_action_refresh_dark));
        items.add(new Item("A propos", R.drawable.ic_action_select_all_dark));
    
        // A custom ListView is needed so the drawer can be notified when it's
        // scrolled. This is to update the position
        // of the arrow indicator.
        mList = new ListView(this);
        mAdapter = new MenuAdapter(items);
        mList.setAdapter(mAdapter);
        mList.setOnItemClickListener(mItemClickListener);
    
        mMenuDrawer.setMenuView(mList);
    
    }
    
    private void setupFragments() {
    
        mmyMapFragment = new myMapFragment();
    
        mmyMonCompteFragment = new myMonCompteFragment();
        mmyPaiementFragment = new myPaiementFragment();
        mmyReservationsFragment = new myReservationsFragment();
        mmyFavorisFragment = new myFavorisFragment();
        mmyCodePromoFragment = new myCodePromoFragment();
        mmyAboutFragment = new myAboutFragment();
    
        mmyFragment = new ArrayList<Object>();
    
        mmyFragment.add(mmyMapFragment);
        mmyFragment.add(mmyMonCompteFragment);
        mmyFragment.add(mmyPaiementFragment);
        mmyFragment.add(mmyReservationsFragment);
        mmyFragment.add(mmyFavorisFragment);
        mmyFragment.add(mmyCodePromoFragment);
        mmyFragment.add(mmyAboutFragment);
    
    
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager
                .beginTransaction();
        fragmentTransaction.replace(R.id.myContenu, mmyMapFragment);
        fragmentTransaction.commit();
    
        currentFragment = mmyMapFragment;
    }
    
    private AdapterView.OnItemClickListener mItemClickListener = new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position,
                long id) {
            mActivePosition = position;
            mMenuDrawer.setActiveView(view, position);
            mMenuDrawer.closeMenu();
    
            if ((mmyFragment.get(position) != null)
                    /*&& (mmyFragment.get(position).getClass() != currentFragment
                            .getClass())*/) {
    
                Fragment nexFragment = (Fragment) mmyFragment
                        .get(position);
    
                FragmentManager fragmentManager = getSupportFragmentManager();
                FragmentTransaction fragmentTransaction = fragmentManager
                        .beginTransaction();
                fragmentTransaction.setCustomAnimations(android.R.anim.fade_in,
                        android.R.anim.fade_out);
                fragmentTransaction.hide(currentFragment);
                if (!nexFragment.isHidden()) {
                    //fragmentTransaction.add(nexFragment, nexFragment.getTag());
                    Toast.makeText(
                            getApplicationContext(),
                            ""
                                    + nexFragment.getClass().toString()
                                    + " : "
                                    + mmyFragment.indexOf(mmyFragment
                                            .get(position)), Toast.LENGTH_SHORT).show();
                }
                //fragmentTransaction.addToBackStack(nexFragment.getTag());
                fragmentTransaction.attach(nexFragment);
                fragmentTransaction.replace(R.id.myContenu, nexFragment);
                //fragmentTransaction.show(nexFragment);
    
                currentFragment = nexFragment;
                fragmentTransaction.commit();...}
    

След един ден най-накрая намерих отговора тук

Така че току-що внедрих кода по-долу. Но трябва да използвам replace();, така че ще намеря начин да запазя състоянието на картата си.

public void onDestroyView ()
{
      try{
    SupportMapFragment fragment = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.map));
        FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
        ft.remove(fragment);
        ft.commit();
      }catch(Exception e){
      }
    super.onDestroyView();  
}

person Glenn Sonna    schedule 16.05.2013    source източник