2013-08-13 17 views
27

Mam fragment, który jest częścią ViewPagera i chcę użyć Google Map V2 wewnątrz tego fragmentu. To, co starałem tak daleko,Jak korzystać z mapy google V2 wewnątrz fragmentu?

W moim fragmentu

private SupportMapFragment map; 
     private GoogleMap mMapView; 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     // TODO Auto-generated method stub 
     super.onActivityCreated(savedInstanceState); 

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



    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     if (mMapView == null) { 
      mMapView = map.getMap(); 
      Marker hamburg = mMapView.addMarker(new MarkerOptions().position(HAMBURG) 
         .title("Hamburg")); 
        Marker kiel = mMapView.addMarker(new MarkerOptions() 
         .position(KIEL) 
         .title("Kiel") 
         .snippet("Kiel is cool") 
         .icon(BitmapDescriptorFactory 
          .fromResource(R.drawable.ic_launcher))); 


        mMapView.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15)); 

        // Zoom in, animating the camera. 
      mMapView.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null); 


     } 
    } 

iw moim układ subfragment_info.xml mam,

<fragment 
      android:id="@+id/map" 
      class="com.google.android.gms.maps.SupportMapFragment" 
      android:layout_width="match_parent" 
      android:layout_height="300dp" 
      android:layout_alignParentLeft="true" 
      android:layout_below="@+id/tableLayout1" /> 

widzę mapę teraz. Ale znaczniki nie są wyświetlane. Myślę, że moja mapa Google mMapView ma wartość null. Pomóż mi rozwiązać ten problem. Z góry dziękuję.

Odpowiedz

49

utworzyć ramkę na mapie, w którym zostanie on dodany w układzie xml

<RelativeLayout 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:id="@+id/map_container"> 

<!-- The map fragments will go here --> 
</RelativeLayout> 

Nie obejmują class = "com.google.android. gms.maps.SupportMapFragment”w xml w swojej klasie fragment albo rozumiem ręcznie wewnątrz onActivityCreated

@Override 
public void onActivityCreated(Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 
    FragmentManager fm = getChildFragmentManager(); 
    fragment = (SupportMapFragment) fm.findFragmentById(R.id.map_container); 
    if (fragment == null) { 
     fragment = SupportMapFragment.newInstance(); 
     fm.beginTransaction().replace(R.id.map_container, fragment).commit(); 
    } 


/***at this time google play services are not initialize so get map and add what ever you want to it in onResume() or onStart() **/ 
} 

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

jeśli wy napotkają żadnych problemów Illegal State Exception wystąpić tylko napisać poniżej kod

/* * Kwestia ta jest śledzone w (Google Bugs) * http://code.google.com/p/gmaps-api-issues/issues/detail?id=5064 Dodany * Kod ze względu na nielegalne State wyjątek występuje, gdy na karcie reclicking * * krótkotrwałe obejście, które stały się dla mnie jest to, aby dodać następujące * onDetach() każdego Fra gment którą nazywasz */

@Override 
    public void onDetach() { 
     super.onDetach(); 

     try { 
      Field childFragmentManager = Fragment.class 
        .getDeclaredField("mChildFragmentManager"); 
      childFragmentManager.setAccessible(true); 
      childFragmentManager.set(this, null); 

     } catch (NoSuchFieldException e) { 
      throw new RuntimeException(e); 
     } catch (IllegalAccessException e) { 
      throw new RuntimeException(e); 
     } 
    } 

// Jeśli chcesz wyświetlić mapę aktywności tylko przedłużyć swoją aktywność przez // FragmentActivity kodu zapisu wzmianki poniżej

W onCreate

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

W onResume

@Override 
    protected void onResume() { 
     super.onResume(); 
     if (googleMap == null) { 
      initilizeMap(); 

     } 
    } 

private void initilizeMap() { 
     if (googleMap != null) { 

      googleMap = fragment.getMap(); 
      googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); 
      googleMap.getUiSettings().setMyLocationButtonEnabled(true); 
      googleMap.getUiSettings().setCompassEnabled(true); 
      googleMap.getUiSettings().setRotateGesturesEnabled(true); 

      CameraPosition cameraPosition = new CameraPosition.Builder() 
        .target(new LatLng(latitude, longitude)).zoom(10).build(); 
      googleMap.animateCamera(CameraUpdateFactory 
        .newCameraPosition(cameraPosition)); 

      // create marker 
      MarkerOptions marker = new MarkerOptions().position(new LatLng(
        latitude, longitude)); 
      // ROSE color icon 
      marker.icon(BitmapDescriptorFactory 
        .defaultMarker(BitmapDescriptorFactory.HUE_ROSE)); 
      // adding marker 
      googleMap.addMarker(marker); 

      // check if map is created successfully or not 
      if (googleMap == null) { 
       Toast.makeText(getApplicationContext(), 
         "Sorry! unable to create maps", Toast.LENGTH_SHORT) 
         .show(); 
      } 
     } 
    } 

Dodatkowa pomoc może uzyskać od tych lin KS
https://code.google.com/p/gmaps-api-issues/issues/detail?id=5064#c1 https://developers.google.com/maps/documentation/android/map

+0

Działa idealnie! Wielkie dzięki ! – Cocorico

+0

Dzięki za wsparcie dla mojej odpowiedzi. Odpowiadam tylko na te pytania, które wdrożyłem podczas mojej pracy nad tworzeniem aplikacji. @ Happy developing – DeepakPanwar

+0

@DeepakPanwar: Gr8 Działa. !! –

0

To jak to zrobiłem

w układzie:

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

w postaci kodu:

public class GPS extends FragmentActivity { 

@Override 
protected void onResume() { 
    super.onResume(); 
    setUpMapIfNeeded(); 
} 

private void setUpMapIfNeeded() { 
    // Do a null check to confirm that we have not already instantiated the map. 
    if (supportMap == null) { 
     // Try to obtain the map from the SupportMapFragment. 
     supportMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)) 
       .getMap(); 
     // Check if we were successful in obtaining the map. 
     if (supportMap != null) { 
      MarkerOptions mo = new MarkerOptions().position(new LatLng(latitude, longitude)); 
      supportMap.addMarker(mo); 
     } 
    } 
} 
} 

Zajęło mi dużo błahy, trzeba tylko odpowiednią kombinację rzeczy, upewnij się, że twoja klasa rozszerza FragmentActivity

+0

Dzięki kolego, Właściwie używam fragmentu. Nie aktywność. Czy to rozwiązanie działa na fragment? –

+0

To rozwiązanie nie działa z poziomu fragmnetu – Arno

12

Musisz zdecydować, czy utworzysz swój fragment c od new SupportMapFragment() lub nadmuchać z xml class="com.google.android.gms.maps.SupportMapFragment".

W rzeczywistości nie można mieć Fragment w formacie xml dla innego Fragment. Przeczytaj o nested Fragments.

Możesz śledzić this comment, jak dodać zagnieżdżone SupportMapFragment.

1

moje podejście jest:

Bundle bundle = new Bundle(); 
bundle.putInt(MY_ID, id); 

FragmentManager fm = getFragmentManager(); 
Fragment fragment = fm.findFragmentById(R.id.customer_details_fragment); 

fragment = new SalesFragment(); 
fm.beginTransaction() 
    .add(R.id.customer_details_fragment, fragment) 
    .commit(); 

fragment.setArguments(bundle); 
+1

Dzięki, ale używasz działania. Mój jest Fragment. –

+0

true, sec im zmieniając go. – bofredo

1

Dla MapFragment

<fragment 
    android:id="@+id/map" 
    android:name="com.google.android.gms.maps.MapFragment" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" /> 

w twojej Fragment Klasa

map = ((MapFragment) getActivity().getFragmentManager() 
      .findFragmentById(R.id.map)).getMap(); 
    map.addMarker(new MarkerOptions().position(
      new LatLng(13.031902, 80.278823)).title("Marker Title")); 

Dla SupportMapFragment

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

W swojej Fragment Klasa

map = ((SupportMapFragment) getActivity().getSupportFragmentManager() 
      .findFragmentById(R.id.map)).getMap(); 
    map.addMarker(new MarkerOptions().position(
      new LatLng(13.031902, 80.278823)).title("Marker Title")); 

Uwaga - SupportMapFragment mapie renderowanie raz użytkownik touchs mapę

7

miałem mniej więcej ten sam problem. Miałem szufladę nawigacji i chciałem umieścić mapę w jednym fragmencie.

Śledziłem ten wątek (ale jest w języku hiszpańskim): https://groups.google.com/forum/#!msg/desarrolladores-android/1cvqPm0EZZU/Q801Yvb2ntYJ

Kluczem było (moim zdaniem), aby zmienić plik layout.xml: Zamiast „fragment” wewnątrz „układu subfragment_info .xml”trzeba by zmienić to:

<com.google.android.gms.maps.MapView xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/map" 
android:layout_width="match_parent" 
android:layout_height="match_parent" />` 

Tutaj jest kod wewnątrz wątku (można go używać i dostosować): https://groups.google.com/d/msg/desarrolladores-android/1cvqPm0EZZU/9srw_9feamUJ

+1

Dziękuję za to rozwiązanie. Używałem też szuflady nawigacji i chciałem osobnego fragmentu mapy. Korzystając z Twojego rozwiązania, udało mi się sprawić, że działa poprawnie. To rozwiązanie naprawia również dziwny błąd podczas zmiany orientacji ekranu (mapa nie jest wyświetlana/renderowana, ale tylko znaczniki na niej) –

+0

Dziękuję, sprawdzę to ... –

1

W linku, odpowiedź dla Ciebie:

"Problem polega na tym, że tego, co próbujesz zrobić, nie powinno być robione. Nie powinieneś pompować fragmentów wewnątrz innych fragmentów. Z dokumentacji Androida:

Uwaga: Nie można nadmuchać układu do fragmentu, gdy zawiera on układ a. Zagnieżdżone fragmenty są obsługiwane tylko przy dynamicznym dodawaniu do fragmentu.

Chociaż możesz być w stanie wykonać zadanie za pomocą przedstawionych tu hacków, sugeruję, żebyś tego nie robił. Nie można mieć pewności, że te hacki poradzą sobie z każdym nowym systemem operacyjnym Android, gdy spróbujesz nadpisać układ fragmentu zawierającego inny fragment.

Jedynym Android obsługiwane sposobem na dodanie fragmentu do innego fragmentu odbywa się za pomocą transakcji od kierownika fragmentu dziecko „

W tym problem.

Duplicate ID, tag null, or parent id with another fragment for com.google.android.gms.maps.MapFragment

dla mnie najlepszy rozwiązaniem są @DeepakPanwar

0

Jeśli zastąpię fragment, w którym znajduje się fragment mapy (w tym przykładzie kodu MyFragment) z innym fragmentem, a następnie wracam, otrzymuję IllegalStateException

public class Home_Map extends Fragment { 

GoogleMap googleMap; 
FragmentManager myFragmentManager; 
SupportMapFragment mySupportMapFragment; 
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    // TODO Auto-generated method stub 
    View rootView = inflater.inflate(R.layout.fragment_home__map, container, false); 

    //googleMap.setMyLocationEnabled(true); 

     try { 
      // Loading map 
      initilizeMap(); 
      googleMap.setMyLocationEnabled(true); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    return rootView; 
} 
private void initilizeMap() { 

     try 
     { 
     if (googleMap == null) { 
      myFragmentManager = getFragmentManager(); 
      mySupportMapFragment = (SupportMapFragment)myFragmentManager.findFragmentById(R.id.map2); 
      googleMap = mySupportMapFragment.getMap(); 

      if (googleMap == null) { 
       Toast.makeText(getActivity().getApplicationContext(), 
         "Sorry! unable to create maps", Toast.LENGTH_SHORT) 
         .show(); 
      } 
     } 
     } catch (Exception e) { Toast.makeText(getActivity().getApplicationContext(), ""+e, 1).show(); 
      // TODO: handle exception 
     } 
    } 

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

     initilizeMap(); 

    } 

    @Override 
    public void onDetach() { 
     // TODO Auto-generated method stub 
     super.onDetach(); 
      try { 
       Field childFragmentManager = Fragment.class 
         .getDeclaredField("mChildFragmentManager"); 
       childFragmentManager.setAccessible(true); 
       childFragmentManager.set(this, null); 

      } catch (NoSuchFieldException e) { 
       throw new RuntimeException(e); 
      } catch (IllegalAccessException e) { 
       throw new RuntimeException(e); 
      } 
    } 

    } 
1

Na mapie załadować do fragmentu:

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

Dla .java:

public class PathFragment extends Fragment { 
    View view; 
    GoogleMap mMap; 
    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     view=inflater.inflate(R.layout.fragment_path,null); 
     setupMap(); 
     return view; 
    } 

    private void setupMap() 
    { 
     if (mMap == null) 
     { 
      mMap = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.fragment_map1)).getMap(); 
      mMap.getUiSettings().setZoomControlsEnabled(true); 
     } 

     mMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() { 
      @Override 
      public void onMapLoaded() { 
       getlocation(); 
      } 
     }); 
    } 

    public void getlocation() 
    { 
     try 
     { 
      /*Collect Source and destination latitude and longitude 
      * To draw Polyline 
      * */ 

      LatLng src = new LatLng(Double.parseDouble(AppGlobal.WorkerHistory.getOrder_lat()),Double.parseDouble(AppGlobal.WorkerHistory.getOrder_lng())); 
      LatLng dest =new LatLng(Double.parseDouble(AppGlobal.WorkerHistory.getWorker_lat()),Double.parseDouble(AppGlobal.WorkerHistory.getWorker_lng())); 

      //Add Marker 
      mMap.addMarker(new MarkerOptions() 
       .position(src) 
       .title("Source") 
       .icon(BitmapDescriptorFactory.fromResource(R.drawable.srcicon))); 


      mMap.addMarker(new MarkerOptions() 
       .position(dest) 
       .title("Destination") 
       .icon(BitmapDescriptorFactory.fromResource(R.drawable.desticon))); 



      Polyline line = mMap.addPolyline(
       new PolylineOptions().add(
        new LatLng(src.latitude, src.longitude), 
        new LatLng(dest.latitude, dest.longitude) 
       ).width(5).color(Color.RED).geodesic(true) 
      ); 

      //set zoom level 
      LatLngBounds.Builder builder = new LatLngBounds.Builder(); 
      builder.include(src); 
      builder.include(dest); 
      LatLngBounds bounds = builder.build(); 

      int padding = 0; // offset from edges of the map in pixels 
      CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding); 
      mMap.animateCamera(cu); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 
} 
+0

wykorzystania tego pliku w układzie, –

+0

Powiązane problemy