2016-04-23 89 views
3

我會嘗試在名爲RoeteFragment的片段上的Android應用程序中顯示地圖。如果我調試我的代碼,我發現方法onMapReady永遠不會被調用,所以地圖不會加載。MapView.onMapReady從未在Fragment中調用Map Map在MapView中加載

該片段執行OnMapReadyCallback像需要和在onCreateView我得到MapView並呼籲getMapAsync。如果我在該方法上放置一個斷點,它將一直被擊中,onMapReady內的斷點從未被擊中。沒有異常拋出。

我在文件res/values/google_maps_api.xml中也有一個有效的Google Maps API密鑰。

這裏是我的代碼:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

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

</RelativeLayout> 
public class RoeteFragment extends Fragment implements OnMapReadyCallback { 

    private MapView mapView; 
    private static Roete _roete; 

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

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.fragment_roete, container, false); 
     mapView = (MapView) view.findViewById(R.id.map); 
     mapView.getMapAsync(this); 
     return view; 
    } 

    @Override 
    public void onMapReady(GoogleMap googleMap) { 

     if (_roete != null && _roete.getAankomstLocatie() != null && _roete.getVertrekLocatie() != null) { 
      LatLng aankomst = new LatLng(_roete.getAankomstLocatie().getLatitude(), _roete.getAankomstLocatie().getLongitude()); 
      googleMap.addMarker(new MarkerOptions().position(aankomst).title("aankomst")); 
      googleMap.moveCamera(CameraUpdateFactory.newLatLng(aankomst)); 

      LatLng vertrek = new LatLng(_roete.getVertrekLocatie().getLatitude(), _roete.getVertrekLocatie().getLongitude()); 
      googleMap.addMarker(new MarkerOptions().position(vertrek).title("vertrek")); 
      googleMap.moveCamera(CameraUpdateFactory.newLatLng(vertrek)); 
     } 
    } 

    public static Fragment newInstance() { 
     return new RoeteFragment(); 
    } 

    public static Fragment newInstance(Roete roete) { 
     _roete = roete; 
     return newInstance(); 
    } 
} 

你能提交的bug在我的代碼?

+1

嘗試使用支持地圖片段。 它也將工作在碎片。 https://developers.google.com/android/reference/com/google/android/gms/maps/SupportMapFragment – androidnoobdev

+0

@androidnoobdev:非常感謝它現在的工作:) –

+0

@androidnoobdev:只有一個問題,我看到的是我可以不使用地圖。我的意思是我無法縮放或移動相機。 –

回答

9

閱讀MapView documentation。特別是:

這個類的用戶必須轉發從ActivityFragment含有此視圖在這個類中對應的所有生命週期方法。特別是,你必須在下列方法轉發:

  • onCreate(Bundle)
  • onResume()
  • onPause()
  • onDestroy()
  • onSaveInstanceState()
  • onLowMemory()
+0

這應該是正確的答案,因爲它仍然基於MapView。 –

0

通過從@androidnoobdev,他說要用SupportMapFragment,我已經更新我的佈局文件發送給這個代碼中的註釋:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
      xmlns:android="http://schemas.android.com/apk/res/android" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent"> 

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

</RelativeLayout> 

更新 刪除MapView的支持後B'Z不需要分段。

由於@androidnoobdev

1

嘗試使用支持地圖片段。它也將工作在碎片。 https://developers.google.com/android/reference/com/google/android/gms/maps/SupportMapFragment#developer-guide

攝像頭和縮放級別檢查這一點 - https://developers.google.com/maps/documentation/android-api/views#introduction

試試這個,如果它幫助接受它作爲回答。

+0

感謝您更新我的答案,確實是正確的代碼! :)這個答案並沒有幫助我... –

+0

我已經upvote你的答案,謝謝你的幫助。 –

+0

@ H.Pauwelyn y?看到你仍然在使用地圖視圖可能是這個原因。嘗試使用支持片段更改代碼,然後嘗試鏈接中提到的相機工廠對象。你需要代碼才能更新。 – androidnoobdev

0

您應該從doc注意到這一點:

完全互動的模式使用API​​的MapView類的用戶必須將所有的活動生命週期方法在MapView類中的相應方法。生命週期方法的例子包括onCreate()onDestroy()onResume()onPause()

精簡版模式使用MapView類,轉發生命週期事件是可選的,除了以下情況:

  • 它是強制性調用onCreate(),否則沒有地圖將出現。

  • 如果你想展示你的精簡版模式的地圖我的位置點,並使用默認的位置源,你將需要調用onResume()onPause(),因爲位置源將只有這些調用之間更新。如果您使用自己的位置來源,則無需調用這兩種方法。

所以,你在onCreateView失蹤mapView.onCreate(mapViewBundle),由於地圖是完全互動模式,你必須照顧整個lifecylce的,是這樣的:

public class RoeteFragment extends Fragment implements OnMapReadyCallback { 

    private static final String MAPVIEW_BUNDLE_KEY = "MapViewBundleKey"; 

    private MapView mapView; 
    private static Roete _roete; 

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

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.fragment_roete, container, false); 
     mapView = (MapView) view.findViewById(R.id.map); 

     // *** IMPORTANT *** 
     // MapView requires that the Bundle you pass contain ONLY MapView SDK 
     // objects or sub-Bundles. 
     Bundle mapViewBundle = null; 
     if (savedInstanceState != null) { 
      mapViewBundle = savedInstanceState.getBundle(MAPVIEW_BUNDLE_KEY); 
     } 
     mapView.onCreate(mapViewBundle); 
     mapView.getMapAsync(this); 
     return view; 
    } 

    @Override 
    public void onMapReady(GoogleMap googleMap) { 

     if (_roete != null && _roete.getAankomstLocatie() != null && _roete.getVertrekLocatie() != null) { 
      LatLng aankomst = new LatLng(_roete.getAankomstLocatie().getLatitude(), _roete.getAankomstLocatie().getLongitude()); 
      googleMap.addMarker(new MarkerOptions().position(aankomst).title("aankomst")); 
      googleMap.moveCamera(CameraUpdateFactory.newLatLng(aankomst)); 

      LatLng vertrek = new LatLng(_roete.getVertrekLocatie().getLatitude(), _roete.getVertrekLocatie().getLongitude()); 
      googleMap.addMarker(new MarkerOptions().position(vertrek).title("vertrek")); 
      googleMap.moveCamera(CameraUpdateFactory.newLatLng(vertrek)); 
     } 
    } 

    public static Fragment newInstance() { 
     return new RoeteFragment(); 
    } 

    public static Fragment newInstance(Roete roete) { 
     _roete = roete; 
     return newInstance(); 
    } 

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

    @Override 
    public void onPause() { 
     super.onPause(); 
     mapView.onPause(); 
    } 

    @Override 
    public void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     Bundle mapViewBundle = outState.getBundle(MAPVIEW_BUNDLE_KEY); 
     if (mapViewBundle == null) { 
      mapViewBundle = new Bundle(); 
      outState.putBundle(MAPVIEW_BUNDLE_KEY, mapViewBundle); 
     } 

     mapView.onSaveInstanceState(mapViewBundle); 
    } 

    @Override 
    public void onLowMemory() { 
     super.onLowMemory(); 
     mapView.onLowMemory(); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     mapView.onDestroy(); 
    } 
} 
2

地圖片段是您膨脹到另一個片段的佈局的一部分(我們稱它爲父級)。膨脹的片段成爲父片段的活動BUT的子片段NOT。你要問父片段的孩子片段經理:

注:只需簡單的延長片段public class MapsFragments extends Fragment implements OnMapReadyCallback {} XML文件

<fragment xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:map="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/map" 
    android:name="com.google.android.gms.maps.SupportMapFragment" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context="net.elektrasoft.Test.MapsFragments" /> 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 

    Log.d("check","onCreateView"); 
    // Inflate the layout for this fragment 
    View view= inflater.inflate(R.layout.fragment_maps_fragments, container, false); 
    // Gets the MapView from the XML layout and creates it 
    final SupportMapFragment myMAPF = (SupportMapFragment) getChildFragmentManager() 
      .findFragmentById(R.id.map); 
    myMAPF.getMapAsync(this); 
    return view; 
}`