2011-10-19 22 views
11

Estoy utilizando la clase compatibilidad androide con el hack para el uso de mapviews en un fragmento de encontrar aquí: https://github.com/petedoyle/android-support-v4-googlemapsAndroid mapview con fragmentos no se puede agregar dos veces?

Por desgracia, lo que estoy encontrando es que si el MapFragment se retira de la actividad, y luego readded, consigo el "Solo se le permite tener un solo MapView en un error de MapActivity".

Entiendo el principio detrás del error, e intenté destruir la vista de mapa en el método de fragmento de Pausa. Desafortunadamente no puedo destruir la vista de mapa completamente, ya que todavía estoy obteniéndolo. Mi código se ve así:

private RelativeLayout layout; 
private MapView mp; 

public void onResume(){ 
    super.onResume(); 
    Bundle args = getArguments(); 
    if(mp == null) 
    { 
     mp = new MapView(getActivity(), this.getString(R.string.map_api_key)); 
     mp.setClickable(true); 
    } 

    String request = args.getString("requestId"); 
    layout = (RelativeLayout) getView().findViewById(R.id.mapholder); 
    layout.addView(mp); 
    //TextView txt = (TextView) getView().findViewById(R.id.arguments); 
    //txt.setText(request); 
} 

public void onPause(){ 
    super.onPause(); 
    layout.removeView(mp); 
    mp = null; 
} 

¿Alguien tiene alguna idea sobre cuál es la referencia que descuido destruir aquí?

Respuesta

15

Tuve el mismo problema. Aquí es cómo lo resolví:

  • Como debe ser sólo una instancia de la MAPview en la actividad, que inicializarlo en el método onCreate de la Actividad:

    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        // initialize MapView programmatically to be used in Fragment : 
        this.mActivityMapView = new MapView(MainActivity.this, getString(R.string.debug_mapview_apikey)); 
    
        setContentView(R.layout.activity_main); 
    } 
    
  • Entonces se recuperan en el fragmento onCreateView método:

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
        this.mMapView = ((MainActivity) getActivity()).getMapView(); 
        return this.mMapView; 
    } 
    
  • Y lo destruyo en el método fragmento OnDestroy:

    public void onDestroy() { 
        NoSaveStateFrameLayout parentView = (NoSaveStateFrameLayout) this.mMapView.getParent(); 
        parentView.removeView(this.mMapView); 
        super.onDestroy(); 
    } 
    
6

Es posible que desee quitar la vista del mapa en el método onPause (en lugar del método OnDestroy)

public void onPause() { 
    NoSaveStateFrameLayout parentView = (NoSaveStateFrameLayout) this.mMapView.getParent(); 
    parentView.removeView(this.mMapView); 
    super.onPause();} 

De esta manera, se puede añadir un MapFragment a la backstack. (FragmentTransaction.addToBackStack impide que se destruya un fragmento)

6

Las respuestas de Max y Bleeker funcionan bien, pero debe tener especial cuidado si desea apoyar los cambios de orientación de la pantalla, como hago yo. Al girar la pantalla, se volverá a llamar a OnCreateView sin llamar al método onPause, por lo que se agregará la vista del mapa dos veces. Para solucionarlo, dentro de OnCreateView hice lo siguiente:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
{ 
    this.mMapView = ((MyGameActivity) getActivity()).getMapView(); 
    if (this.mMapView.getParent()!=null) 
    { 
     NoSaveStateFrameLayout parentView = (NoSaveStateFrameLayout) this.mMapView.getParent(); 
     parentView.removeView(this.mMapView); 
    } 
    return this.mMapView; 
} 
4

He intentado obtener una solución simple a este problema. En la clase que maneja mis detalles de Vista (una extensión RelativeLayout), declaré private static MapView myMapView;.

A continuación, reemplazar el método onFinishInflate() como el siguiente fragmento de código:

@Override 
protected void onFinishInflate() { 
    super.onFinishInflate(); 

    //myMapView = (MapView) findViewById(R.id.map_view); 
    if (myMapView==null) 
     myMapView = new MapView(context, getResources().getString(R.string.map_view_api_key)); 
    if (myMapView.getParent() != null) 
     ((ViewGroup)myMapView.getParent()).removeView(myMapView); 

    myMapView.setClickable(true); 
    myMapView.setEnabled(true); 
    RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); 
    myMapView.setLayoutParams(lp);   
    this.addView(myMapView); 

} 

esta manera usted tiene sólo una instancia de MapView.

0

Así es como he resuelto este problema en el caso de Fragment.

crear el diseño

<LinearLayout 
     android:id="@+id/ll_mapcontainer" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:orientation="vertical" /> 

Usted puede colocar este diseño como en cualquier parte en el archivo XML en el que desea mostrar el mapa

Ahora el Código será así.

package com.yuviii.sample; 

import android.content.Intent; 
import android.net.Uri; 
import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentManager; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 

import com.google.android.gms.maps.GoogleMap; 
import com.google.android.gms.maps.SupportMapFragment; 
import com.google.android.gms.maps.model.LatLng; 
import com.google.android.gms.maps.model.MarkerOptions; 
import com.yuviii.sample.R; 

/** 
* Created by yubraj Poudel on 12/20/15. 
*/ 
public class ContactUsFragment extends Fragment { 
    static final LatLng PRACTICAL_ANSWER_LOCATION = new LatLng(53.558, 9.927); 
    private SupportMapFragment fragment; 
    private GoogleMap map; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View v = inflater.inflate(R.layout.page_contactus, container, false); 
     return v; 
    } 



    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 
        initializeMap(); 
    } 

    private void initializeMap() { 

     FragmentManager fm = getChildFragmentManager(); 
     fragment = (SupportMapFragment) fm.findFragmentById(R.id.ll_mapcontainer); 
     if (fragment == null) { 
      fragment = SupportMapFragment.newInstance(); 
      fm.beginTransaction().replace(R.id.ll_mapcontainer, fragment).commit(); 
     } 

    } 
    @Override 
    public void onResume() { 
     super.onResume(); 
     if (map == null) { 
      map = fragment.getMap(); 
      map.addMarker(new MarkerOptions().position(PRACTICAL_ANSWER_LOCATION)); 
     } 
    } 
} 

Esto funciona para mí. ¡Disfruta!

Cuestiones relacionadas