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 地图问题。
我有一个
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 地图问题。