SupportMapFragmentManagers getMapAsync()不触发onMapReady(GoogleMap map)

时间:2017-04-04 07:56:12

标签: google-maps-android-api-2 supportmapfragment

我有一个

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

     // http://stackoverflow.com/a/36592000/5102206
     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(),在else条件之后mapFragment对象为null。  2.使用getChildFragmentMenager(),mapfragment似乎有效且非null,但onMapReady未触发。

我在这里缺少什么?

3 个答案:

答案 0 :(得分:1)

  

注意:当布局包含a时,您无法将布局扩展为片段。仅在动态添加到片段时才支持嵌套片段

如果你想要在片段中给地图充气,你可以用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>

此外,您不需要在类定义中实现onMapReadyCallback。而不是回调,而是在那里创建一个新的OnMapReadyCallback():

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

您还需要这些

MapView mMapView;
private GoogleMap googleMap;

我希望这会有所帮助!

答案 1 :(得分:1)

主线程上出现了来自RxJava的阻塞线程的问题。所以这不是谷歌地图问题。

答案 2 :(得分:0)

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

如果您查看Google SamplesGoogle Maps示例会使用ActivitySupportMapFragment

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

}