![](/img/trans.png)
[英]How to save Webview state when switching between different Fragments in a Tablayout?
[英]How to save the state of the map when switching between fragments?
當我將片段切換到另一個片段並返回到地圖時,則 Google Map _map 等於 null。
假設我在地圖周圍移動,然后移動到另一個片段並返回到地圖。 當我回到卡上時,它已超載。
如何解決這個問題呢。 非常感謝 ! 然后我不知道該怎么辦。 你有哪些選擇? 也許有人已經在這方面工作了?
public class MapFragment extends Fragment implements OnMapReadyCallback {
private GoogleMap _map;
// The geographical location where the device is currently located. That is, the last-known
// location retrieved by the Fused Location Provider.
private Location _mLastKnownLocation;
SharedManager _manager;
Connect _connect;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
_manager = new SharedManager(getActivity());
_connect = new Connect();
// Retrieve location and camera position from saved instance state.
if (savedInstanceState != null) {
_mLastKnownLocation = savedInstanceState.getParcelable(KEY_LOCATION);
_mCameraPosition = savedInstanceState.getParcelable(KEY_CAMERA_POSITION);
}
// Construct a FusedLocationProviderClient.
_mFusedLocationProviderClient =
LocationServices.getFusedLocationProviderClient(getActivity());
Log.d(TAG, "onCreate");
}
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_map, container, false);
//BuildMap
initializeMap();
Log.d(TAG, "onCreateView");
return root;
}
/**
* Saves the state of the map when the activity is paused.
*/
@Override
public void onSaveInstanceState(Bundle outState) {
if (_map != null) {
outState.putParcelable(KEY_CAMERA_POSITION, _map.getCameraPosition());
outState.putParcelable(KEY_LOCATION, _mLastKnownLocation);
super.onSaveInstanceState(outState);
}
Log.d(TAG, "onSaveInstanceState");
}
@Override
public void onMapReady(GoogleMap googleMap) {
_map = googleMap;
_map.getUiSettings().setZoomControlsEnabled(false);
_map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
// Prompt the user for permission.
getLocationPermission();
// 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();
}
/**
* Gets the current location of the device, and positions the map's camera.
*/
private void getDeviceLocation() {
/*
* Get the best and most recent location of the device, which may be null in rare
* cases when a location is not available.
*/
try {
if (_mLocationPermissionGranted) {
Task<Location> locationResult = _mFusedLocationProviderClient.getLastLocation();
locationResult.addOnCompleteListener(getActivity(), new OnCompleteListener<Location>
() {
@Override
public void onComplete(@NonNull Task<Location> task) {
if (task.isSuccessful()) {
// Set the map's camera position to the current location of the device.
_mLastKnownLocation = task.getResult();
if (_mLastKnownLocation != null) {
_map.moveCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(_mLastKnownLocation.getLatitude(),
_mLastKnownLocation.getLongitude()), 15));
}
} else {
Log.d(TAG, "Current location is null. Using defaults.");
Log.e(TAG, "Exception: %s", task.getException());
_map.moveCamera(CameraUpdateFactory
.newLatLngZoom(mDefaultLocation, DEFAULT_ZOOM));
_map.getUiSettings().setMyLocationButtonEnabled(false);
}
}
});
}
} catch (SecurityException e) {
Log.e("Exception: %s", e.getMessage());
}
}
/**
* Prompts the user for permission to use the device location.
*/
private void getLocationPermission() {
/*
* Request location permission, so that we can get the location of the
* device. The result of the permission request is handled by a callback,
* onRequestPermissionsResult.
*/
if (ContextCompat.checkSelfPermission(
this.getActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
_mLocationPermissionGranted = true;
} else {
ActivityCompat.requestPermissions(this.getActivity(),
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
updateLocationUI();
}
}
/**
* Handles the result of the request for location permissions.
*/
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
_mLocationPermissionGranted = false;
switch (requestCode) {
case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
_mLocationPermissionGranted = true;
}
}
}
updateLocationUI();
}
private void updateLocationUI() {
if (_map == null) {
return;
}
try {
if (_mLocationPermissionGranted) {
_map.setMyLocationEnabled(true);
_map.getUiSettings().setMyLocationButtonEnabled(true);
} else {
_map.setMyLocationEnabled(false);
_map.getUiSettings().setMyLocationButtonEnabled(false);
_mLastKnownLocation = null;
getLocationPermission();
}
} catch (SecurityException e) {
Log.e("Exception: %s", e.getMessage());
}
}
// Build the map.
private void initializeMap() {
if (_map == null) {
SupportMapFragment mapFrag = (SupportMapFragment)
getChildFragmentManager().findFragmentById(R.id.map_View);
assert mapFrag != null;
mapFrag.getMapAsync(this);
}
}
}
這是一個簡單的Fragment
間通信問題。 您在此處有多種選擇:
1) 應用其中一種 MV* 方法 (MVP/MVVM/MVI),它將表示層與所有邏輯和視圖分開。 這些相當復雜,我無法在這里詳細解釋。 另外,如果你熟悉這些,你一開始就不會問這個問題。
2) 最簡單(不是最好)的方法是使用 Application 類(假設它遵循Singleton
模式),或者您可以使用的幾乎任何其他Singleton
類。 只需將數據保存在Fragment
A 中並從Fragement
B 中檢索。 這有缺點,因為您增加了實例之間的內聚力並依賴於Singleton
模式。
3)另一種簡單且更可取的方法是使用簡單的接口(回調)在您的Activity
和Fragment
之間建立雙向通信。 只需在Activity
聲明一個回調接口(或實現它)並將其傳遞給Fragments
。 因此,現在您可以在它們之間傳輸並在Fragment
更改期間將數據存儲在Activity
中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.