【问题标题】:SupportMapFragmentManagers getMapAsync() does not trigger onMapReady(GoogleMap map)SupportMapFragment Managers getMapAsync() 不会触发 onMapReady(GoogleMap map)
【发布时间】:2017-04-04 07:56:12
【问题描述】:

我有一个

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 操作系统设备上: 1.使用getFragmentManager(),mapFragment对象在else条件后为null。 2. 使用 getChildFragmentMenager() 时,mapfragment 似乎有效且非空,但未触发 onMapReady。

我在这里错过了什么?

【问题讨论】:

  • 为什么不使用extend SupportMapFragment或者直接使用呢? Android Jelly(即 API 16)及更高版本涵盖了 95.2% 的 Google Play 支持设备。
  • @JPVentura 我暂时这样做了,但这并没有改变。我得到了同样的结果。
  • 1.为什么要将SupportMapFragment 嵌套在MyMapFragment 中? 2. 为什么要明确检查没有人使用的 API 级别?
  • 我也有同样的问题,是真的。

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


【解决方案1】:

注意:当布局包含 .只有动态添加到片段时才支持嵌套片段

如果你想在片段中膨胀地图,你可以在 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() 而不是 callback

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

你也需要这些

MapView mMapView;
private GoogleMap googleMap;

我希望这会有所帮助!

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      我不太明白你为什么要嵌套片段,特别是因为它会导致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");
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多