[如果它影响任何答案或建议,我最终希望在此应用中看到的是导航UI,其中Fragment
之一是地图。我使用了一个模板,从一个导航UI开始,它给了我几个Fragment
,每个选项卡一个。目前,我正在尝试使用Google API将MapView
放在其中一个Fragment
中。
[通常,这不起作用(显然)。我已启动并运行所有内容,但是当我拉起其中包含地图的选项卡时,地图为空白。没有崩溃,也没有错误输出:
I/Google Maps Android API: Google Play services client version: 12451000
I/Google Maps Android API: Google Play services package version: 201516040
D/NetworkSecurityConfig: No Network Security Config specified, using platform default
I/DynamiteModule: Considering local module com.google.android.gms.googlecertificates:0 and remote module com.google.android.gms.googlecertificates:4
Selected remote version of com.google.android.gms.googlecertificates, version >= 4
我知道我的API密钥有效,因为我有另一个可以按预期工作地图的应用程序。我怀疑我是否需要第二个API密钥,但是无论如何我还是觉得,因为创建第二个API密钥并不是太明显,我认为这种预感是正确的。我使用的大多数代码都是从该工作示例复制而来的;主要区别在于其他示例使用SupportMapFragment
,并且具有class MapsActivity extends FragmentActivity
。在这里,由于我真的不想处理嵌套片段,因此我试图在该片段中使用MapView
。
我的代码中哪些未被复制的部分主要来自在线资源。我尝试过的任何方法都没有产生更好的结果。
[MapView inside fragment正在回答另一个问题
Creating google maps v2 in a fragment using Navigation Drawer仅包含我已经拥有的东西
[android MapView in Fragment给了我使用MapsInitializer.initialize(this.getActivity());
的想法,但这没有帮助
Mapview in separate fragment android没有新内容
[how do i solve integrating google map in fragment in android使用Fragment
而不是MapView
我也知道正在调用onMapReady
。在其中,我移动了相机,随后调用了onCameraMoveStarted
。但是,它不会输入onCameraMove
或onCameraIdle
。
这就是代码,它使用了上面链接中的一些想法。我试图切出不相关的任何内容(其他片段等)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.retailtherapy">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key" />
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:windowSoftInputMode="stateVisible|adjustResize" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>
</manifest>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view"
app:menu="@menu/bottom_nav_menu" />
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
app:defaultNavHost="true"
app:navGraph="@navigation/mobile_navigation"
tools:context=".MainActivity" />
</androidx.constraintlayout.widget.ConstraintLayout>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mobile_navigation"
app:startDestination="@+id/navigation_map">
<fragment
android:id="@+id/navigation_map"
android:name="com.example.retailtherapy.ui.map.MapFragment"
android:label="Map"
tools:layout="@layout/fragment_map" />
</navigation>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.map.MapFragment" >
<com.google.android.gms.maps.MapView
android:id="@+id/googleMap"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
public class MapFragment extends Fragment implements OnMapReadyCallback, LocationListener {
/*************************************************************************
*
* M E M B E R S
*
*/
// Location manager for getting current location
private LocationManager mLocationManager = null;
// The map object for reference for ease of adding points and such
private GoogleMap mGoogleMap = null;
private MapView mMapView = null;
// The camera position tells us where the view is on the map
private CameraPosition mCameraPosition = Constants.GetDefaultCameraPosition();
// Current latitude and longitude of user
private LatLng mCurrentLatLong = new LatLng(0.0, 0.0);
// These are flags that allow us to selectively not move the camera and
// instead wait for idle so the movement isn't jerky
private boolean mCameraMoving = false;
private boolean mPendingUpdate = false;
/*************************************************************************
*
* F R A G M E N T
*
*/
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View root = inflater.inflate(R.layout.fragment_map, container, false);
// The google map...
MapsInitializer.initialize(getActivity());
mMapView = (MapView) root.findViewById(R.id.googleMap);
mMapView.onCreate(savedInstanceState);
mMapView.getMapAsync(this);
// The required permissions...
final String[] REQUIRED_PERMISSIONS = {
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.INTERNET,
};
requestPermissions(REQUIRED_PERMISSIONS, 0);
return root;
}
@Override
public void onStart() throws SecurityException {
super.onStart();
// Location manager for getting info current location
mLocationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, this);
}
@Override
public void onResume() {
super.onResume();
mMapView.onResume();
}
@Override
public void onStop() {
super.onStop();
}
@Override
public void onDestroyView() {
super.onDestroyView();
mMapView.onDestroy();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mMapView.onSaveInstanceState(outState);
}
@Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}
/*************************************************************************
*
* G O O G L E M A P S
*
*/
@Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
// Assuming if here that we have permissions okay. Dangerous sure
// but I'm lazy...
mGoogleMap.setMyLocationEnabled(true);
// Store the location of the camera for UI purposes so we can go
// back to where we were
mGoogleMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {
@Override
public void onCameraMove() {
mCameraPosition = mGoogleMap.getCameraPosition();
}
});
mGoogleMap.setOnCameraMoveStartedListener(new GoogleMap.OnCameraMoveStartedListener() {
@Override
public void onCameraMoveStarted(int i) {
mCameraMoving = true;
}
});
mGoogleMap.setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener() {
@Override
public void onCameraIdle() {
mCameraMoving = false;
if (mPendingUpdate) {
centerCameraOnLocation(false);
}
}
});
// Start with user centered in view
centerCameraOnLocation(true);
}
/*************************************************************************
*
* L O C A T I O N
*
*/
@Override
public void onLocationChanged(Location location) {
// Store the current location so if we start auto-center but aren't
// already, we know where to pan to
LatLng newLatLng = new LatLng(location.getLatitude(), location.getLongitude());
if (!newLatLng.equals(mCurrentLatLong)) {
mCurrentLatLong = new LatLng(location.getLatitude(), location.getLongitude());
centerCameraOnLocation(false);
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
@Override
public void onProviderDisabled(String provider) {}
@Override
public void onProviderEnabled(String provider) {}
/*************************************************************************
*
* M A P C A M E R A
*
*/
/*
* Updates the camera position based on current state. If the camera is
* already moving, then wait.
*/
private void centerCameraOnLocation(boolean animate) {
if (mGoogleMap == null) {
return;
}
if (mCameraMoving) {
mPendingUpdate = true;
return;
}
// Get the CameraPosition to update to based on whether we are auto
// centering or not.
if (mCameraPosition == null) {
mCameraPosition = Constants.GetDefaultCameraPosition();
}
// If this is the same as it was before, then don't reset it
if (mCameraPosition.equals(mGoogleMap.getCameraPosition())) {
return;
}
// Make the update so we can move the camera
CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(mCameraPosition);
// Move the camera with or without animation. The time we don't want
// animation is when we're setting the position initially
if (animate) {
mGoogleMap.animateCamera(cameraUpdate);
}
else {
mGoogleMap.moveCamera(cameraUpdate);
}
mPendingUpdate = false;
}
}
最后我在https://stackoverflow.com/a/51464293/3038157的评论中找到了答案。
[基本上,似乎有些陈旧。在不更改任何代码的情况下,我卸载了该应用程序,对其进行了清理,重新构建,并保证其可以正常工作。