SupportMapFragmentManagers getMapAsync() 不触发onMapReady(GoogleMap地图)

SupportMapFragmentManagers getMapAsync() does not trigger onMapReady(GoogleMap map)

我有一个

public abstract class MyMapFragment implements OnMapReadyCallback
{
  //
  public GoogleMap googleMap;
  SupportMapFragment mapFragment;

  @IdRes
  public abstract int getSupportMapFragId();

  @Override
  public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
     super.onViewCreated(view, savedInstanceState);

     // 
     if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
        // Do something for lollipop and above versions
        mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(getSupportMapFragId());
    } else {
        // do something for phones running an SDK before lollipop
        mapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(getSupportMapFragId());
    }
    mapFragment.getMapAsync(this);

  }

  //..

  @Override
  public void onMapReady(GoogleMap map) {
     this.googleMap = map;
  }
}

根据我的断点,调用了onViewCreated(),但是没有调用onMapReady()(this.googleMap = map上的断点没有触发)

在 Android 5、6 和 7 上它到目前为止工作正常,我可以看到地图.. 在 Android 4.X (API 16 - API 19) 台设备上,我的应用程序启动了,但随后它似乎在那里冻结了……我看到一个白色的空白屏幕。

在 Android 4.X OS 设备上: 1、用getFragmentManager(),mapFragment对象在else条件后为null。 2. 使用 getChildFragmentMenager() 时,mapfragment 似乎有效且非空,但未触发 onMapReady。

我在这里错过了什么?

我不太明白你为什么要嵌套片段,特别是因为它会导致 performance issues

如果你看一下 Google Samples, the Google Maps examples uses an Activity and SupportMapFragment:

public class MapsActivityCurrentPlace extends AppCompatActivity
            implements OnMapReadyCallback, ConnectionCallbacks,
            OnConnectionFailedListener {

    @Override
    public void onMapReady(GoogleMap map) {
        mMap = map;

        // Use a custom info window adapter to handle multiple lines of text in the
        // info window contents.
        mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {

            @Override
            // Return null here, so that getInfoContents() is called next.
            public View getInfoWindow(Marker arg0) {
                return null;
            }

            @Override
            public View getInfoContents(Marker marker) {
                // Inflate the layouts for the info window, title and snippet.
                View infoWindow = getLayoutInflater().inflate(R.layout.custom_info_contents,
                        (FrameLayout)findViewById(R.id.map), false);

                TextView title = ((TextView) infoWindow.findViewById(R.id.title));
                title.setText(marker.getTitle());

                TextView snippet = ((TextView) infoWindow.findViewById(R.id.snippet));
                snippet.setText(marker.getSnippet());

                return infoWindow;
            }
        });

        // Turn on the My Location layer and the related control on the map.
        updateLocationUI();

        // Get the current location of the device and set the position of the map.
        getDeviceLocation();
    }

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

        if (savedInstanceState != null) {
            mLastKnownLocation = savedInstanceState.getParcelable(KEY_LOCATION);
            mCameraPosition = savedInstanceState.getParcelable(KEY_CAMERA_POSITION);
        }

        setContentView(R.layout.activity_maps);

        mGoogleApiClient = new GoogleApiClient.Builder(this)
            .enableAutoManage(this /* FragmentActivity */,
                    this /* OnConnectionFailedListener */)
            .addConnectionCallbacks(this)
            .addApi(LocationServices.API)
            .addApi(Places.GEO_DATA_API)
            .addApi(Places.PLACE_DETECTION_API)
            .build();

        mGoogleApiClient.connect();
    }

    @Override
    public void onConnected(Bundle connectionHint) {
        SupportMapFragment mapFragment =
            (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult result) {
        Log.d(TAG, result.getErrorMessage());
    }

    @Override
    public void onConnectionSuspended(int cause) {
        Log.d(TAG, "Play services connection suspended");
    }

}

Note: You cannot inflate a layout into a fragment when that layout includes a . Nested fragments are only supported when added to a fragment dynamically

如果你想在片段中膨胀地图,你可以在 xml 中进行,也可以在 java 中进行,代码如下:

    @Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    FragmentManager fm = getChildFragmentManager();
    SupportMapFragment mapFragment = (SupportMapFragment) fm.findFragmentByTag("mapFragment");
    if (mapFragment == null) {
        mapFragment = new SupportMapFragment();
        FragmentTransaction ft = fm.beginTransaction();
        ft.add(R.id.mapFragmentContainer, mapFragment, "mapFragment");
        ft.commit();
        fm.executePendingTransactions();
    }
    mapFragment.getMapAsync(callback);
}

还有简单的容器

  <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mapFragmentContainer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
</LinearLayout>

此外,您不需要在 class 定义中实现 onMapReadyCallback。您可以在此处创建一个新的 OnMapReadyCallback() 而不是 callback

MapView.getMapAsync(new OnMapReadyCallback() {
        @Override
        public void onMapReady(GoogleMap mMap) {
            googleMap = mMap;
                }
            });

你还需要这些

MapView mMapView;
private GoogleMap googleMap;

希望对您有所帮助!

主线程上来自 RxJava 的阻塞线程存在问题。所以这不是 Google 地图问题。