我有一个带导航抽屉的应用程序,并在用户选择导航项后使用片段显示新屏幕
我的MainActivity类中处理它的部分如下所示:
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_new) {
addFragment(new NewFragment(), id);
} else if (id == R.id.nav_start) {
addFragment(new StartFragment(), id);
} else if (id == R.id.nav_delete) {
addFragment(new DeleteFragment(), id);
} else if (id == R.id.nav_gps) {
addFragment(new GPSFragment(), id);
}
...
addFragment
方法如下所示:
public void addFragment(Fragment fragment, int id) {
if (fragment != null) {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
if (fragmentManager.getFragments() == null) {
fragmentTransaction.replace(R.id.fragment_container, fragment, fragment.getClass().getSimpleName())
.commit();
} else {
fragmentTransaction.replace(R.id.fragment_container, fragment, fragment.getClass().getSimpleName())
.addToBackStack(Integer.toString(id))
.commit();
}
}
}
其中一个片段是GPS,我实施了谷歌地图。它有效,但有两个主要问题,我不知道发生了什么:
这必须归功于我实施谷歌地图的方式,或者更具体地说是我处理不同州(可能)之间转换的方式。我认为,按照我实施代码的方式,每当我使用导航抽屉,或按后退按钮,或按回家离开GPS片段时,gmaps将断开连接,片段将被暂停。
我不确定为什么会导致这种速度减慢,或者将应用重新启动回MainActivity。也许是记忆问题?我不知道如果我总是从gmaps断开连接并在我离开时删除片段会导致什么。在添加代码以使mMapView.getMapAsync(this)
正常工作之前,我不认为这是一个问题,所以它可能与mapready事件及其与导航的交互方式有关吗?
GPS片段只是监听lat,lon位置的变化,并移动摄像机和标记以使用户位置居中。这是GPSFragment类:
public class GPSFragment extends Fragment implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener, OnMapReadyCallback {
private GoogleMap googleMap;
private GoogleApiClient mGoogleApiClient;
double lat, lon;
LocationRequest mLocationRequest;
CoordinatorLayout coordinatorLayout;
UiSettings mapSettings;
CameraPosition cameraPosition;
MarkerOptions markerOptions;
Marker marker;
Location mLastLocation;
MapView mMapView;
public GPSFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
coordinatorLayout = (CoordinatorLayout) getActivity().findViewById(R.id.coordinator_layout);
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_gps, container, false);
//Set the nav drawer item highlight
MainActivity mainActivity = (MainActivity) getActivity();
mainActivity.navigationView.setCheckedItem(R.id.nav_gps);
//Set actionbar title
mainActivity.setTitle("GPS");
//Create api connector and map
buildGoogleApiClient();
mMapView = (MapView) view.findViewById(R.id.mapView);
mMapView.onCreate(savedInstanceState);
//mMapView.onResume();
//When map is ready, set it up with a onMapReady callback
mMapView.getMapAsync(this);
return view;
}
@Override
public void onResume() {
super.onResume();
if (mGoogleApiClient.isConnected()) {
mMapView.onResume();
} else {
mGoogleApiClient.connect();
mMapView.onResume();
}
}
@Override
public void onPause() {
super.onPause();
if (mGoogleApiClient.isConnected()) {
mMapView.onPause();
mGoogleApiClient.disconnect();
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mGoogleApiClient.isConnected()) {
mMapView.onDestroy();
mGoogleApiClient.disconnect();
}
}
@Override
public void onLowMemory() {
super.onLowMemory();
if (mGoogleApiClient.isConnected()) {
mMapView.onLowMemory();
mGoogleApiClient.disconnect();
}
}
@Override
public void onConnected(Bundle bundle) {
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(100); // Update location every second
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
lat = mLastLocation.getLatitude();
lon = mLastLocation.getLongitude();
}
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onLocationChanged(Location location) {
lat = location.getLatitude();
lon = location.getLongitude();
marker.setPosition(new LatLng(lat, lon));
googleMap.animateCamera(CameraUpdateFactory
.newLatLng(new LatLng(lat, lon)));
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
buildGoogleApiClient();
}
synchronized void buildGoogleApiClient() {
//Request permission for location data
if (ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
//If permission has not been granted
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION)) {
//If they have previously declined permission, show explanation
Snackbar.make(coordinatorLayout, R.string.permission_explain_gps,
Snackbar.LENGTH_INDEFINITE).setAction(R.string.request_permission, new View.OnClickListener() {
@Override
public void onClick(View view) {
ActivityCompat.requestPermissions(getActivity(),
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
0);
}
}).show();
} else {
//If no previous declines
ActivityCompat.requestPermissions(getActivity(),
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
0);
}
} else {
//If permission has been granted
mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
}
@Override
public void onMapReady(GoogleMap mMapView) {
googleMap = mMapView;
setupMap();
}
public void setupMap() {
mapSettings = googleMap.getUiSettings();
mapSettings.setZoomGesturesEnabled(true);
mapSettings.setZoomControlsEnabled(true);
mapSettings.setScrollGesturesEnabled(true);
mapSettings.setTiltGesturesEnabled(true);
mapSettings.setRotateGesturesEnabled(true);
markerOptions = new MarkerOptions().position(new LatLng(lat, lon));
marker = googleMap.addMarker(markerOptions);
cameraPosition = new CameraPosition.Builder()
.target(new LatLng(lat, lon)).zoom(12).build();
googleMap.animateCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
}
}
编辑:还注意到,在关闭并从手机上卸载应用程序后,地图标记图标仍然位于我顶部的状态栏中,我认为只有在手机当前请求位置信息时才会显示...