Java 获取谷歌地图异步,空指针
我在使用Java 获取谷歌地图异步,空指针,java,android,google-maps,Java,Android,Google Maps,我在使用GoogleMap时遇到问题,因为它使用MapView\getmapsync异步获取地图 当我的活动将标记传递给GoogleMap对象时,由于#getMapAsync未及时返回,我遇到NullPointerException 这可以同步完成吗?或者有更好的解决方案吗?将其添加到片段束对我来说不起作用,因为活动可能会在#commit()之后传递片段标记 GoogleMapsFragment public View onCreateView(LayoutInflater inflater,
GoogleMap
时遇到问题,因为它使用MapView\getmapsync
异步获取地图
当我的活动将标记传递给GoogleMap
对象时,由于#getMapAsync
未及时返回,我遇到NullPointerException
这可以同步完成吗?或者有更好的解决方案吗?将其添加到片段束对我来说不起作用,因为活动可能会在#commit()之后传递片段标记
GoogleMapsFragment
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// inflate and return the layout
View v = inflater.inflate(R.layout.fragment_google_map, container,
false);
ButterKnife.bind(this, v);
mMapView.onCreate(savedInstanceState);
mMapView.onResume();// needed to get the map to display immediately
try {
MapsInitializer.initialize(getActivity().getApplicationContext());
} catch (Exception e) {
e.printStackTrace();
}
Bundle bundle = getArguments();
if(bundle != null){
initialMarkers = bundle.getParcelableArrayList("markers");
}
mMapView.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
if (mCameraPos != null) {
mGoogleMap.moveCamera(CameraUpdateFactory.newCameraPosition(mCameraPos));
mCameraPos = null;
} else {
//Set default camera position over the United States.
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(37.09024, -95.712891)).zoom(3).build();
mGoogleMap.moveCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
}
}
});
return v;
}
活动
@OnClick(R.id.loadListOrMapButton)
public void onClickChangeView() {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
if (mLocationListViewFrag.isVisible()) {
if (mGoogleMapFrag == null) {
mGoogleMapFrag = new GoogleMapFragment();
fragmentTransaction.add(R.id.fragment_container, mGoogleMapFrag);
}
bListMapButton.setText(getString(R.string.list));
fragmentTransaction.hide(mLocationListViewFrag).show(mGoogleMapFrag);
} else {
bListMapButton.setText(getString(R.string.map));
fragmentTransaction.hide(mGoogleMapFrag).show(mLocationListViewFrag);
}
fragmentTransaction.commit();
fragmentManager.executePendingTransactions();
updateDisplay();
}
更新显示
public void updateDisplay() {
if (mLocationListViewFrag != null && mLocationListViewFrag.isVisible()) {
Log.d(TAG, "Update Tax Location ListView");
mLocationListViewFrag.setLocations(mLocations);
} else if (mGoogleMapFrag != null && mGoogleMapFrag.isVisible()) {
Log.d(TAG, "Update Google Maps Markers");
//Convert locations to markers to display.
mGoogleMapFrag.clearMarkers();
for (LocationObj aLocation : mLocations) {
mGoogleMapFrag.addMarker(new MarkerOptions().position(
new LatLng(Double.valueOf(aLocation.getLat()), Double.valueOf(aLocation.getLng()))).title(aLocation.getName()));
mGoogleMapFrag.fitBounds();
}
}
}
您应该将处理标记的代码移动到传递给#getmapsync(OnMapReadyCallback回调)
的OnMapReadyCallback
()中。这将确保在地图可用之前不会放置标记
编辑了解更多信息
最终,您必须解决“如果有人在地图未准备好时调用#onClickChangeView
我该怎么办?”从用户体验的角度来看,loadListOrMapButton
甚至在地图完成加载之前都不应该显示。默认情况下,您应该禁用该按钮,然后在您的OnMapReadyCallback
中使用该按钮。您可以将按钮灰显(例如谷歌的“android禁用按钮”),也可以使用View#setVisibility
将其隐藏/显示
非推荐方法
虽然我不太愿意建议,但您可以只检查GoogleMap
是否准备就绪:从您的OnMapReadyCallback
设置一个布尔值,您的外部活动可以检查。差不多
private boolean mapIsReady = false;
mMapView.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(GoogleMap googleMap) {
// your normal code here
mapIsReady = true;
}
});
public boolean mapIsReady() {
return mapIsReady;
}
然后在活动中
@OnClick(R.id.loadListOrMapButton)
public void onClickChangeView() {
// check for null and all that jazz
if (mapsFragment.mapIsReady()) {
// updateDisplay and everything
} else {
// make a toast or something asking them to try later.
}
}
xml
我们需要查看您的代码…@Xoce添加了代码嗯。。。但该活动可能会在回调之前的任何时间传递GoogleMapFragment
。如果您愿意,我添加了上面的代码。在显示和隐藏片段时,我必须使用mapfragment来保存MapView
。MapView充当视图,mapfragment充当片段。没有什么比需要MapFragment来保存MapView更好的了。两者都用于显示地图。您可以在任何布局(如LinearLayout、RelativeLayout等)中保存地图视图或地图片段。
<com.google.android.gms.maps.MapView
android:id="@+id/mapview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:apiKey="@string/google_app_id"
android:clickable="true">
</com.google.android.gms.maps.MapView>
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
LatLng sydney = new LatLng(33.8650, 151.2094);
MapView mapView;
GoogleMap map;
@Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_main);
mapView = (MapView) findViewById(R.id.mapview);
mapView.getMapAsync(this);
MapsInitializer.initialize(this); /* initialize method should be called when we are not sure that map will be loaded before using it. It initialises the map.*/
mapView.onCreate(null);
mapView.onResume();
}
@Override
public void onMapReady(GoogleMap googleMap) {
map = googleMap;
map.addMarker(new MarkerOptions().position(sydney).draggable(true));
}
}