Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 获取谷歌地图异步,空指针_Java_Android_Google Maps - Fatal编程技术网

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));
    }
}