我正在使用 Android Studio 用 Java 实现 Android 应用程序。我们使用 Jetpack Compose 遵循 MVVM 架构,并且有一个包含各种片段的导航栏,包括主页片段等。在主页片段中,我有一个使用 OsmDroid 实现的地图。
我的问题是,在使用 homefragment.xml、HomeFragment.java、HomeViewModel.java、MainActivity.java 和 MainActivity.xml 组织项目后,我尝试通过 MainActivity 管理权限请求,并对其他类执行必要的操作。该应用程序可以工作,但是当我将地图移动到特定位置,然后使用导航栏更改片段时,返回地图会将其值重置为我的活动位置所在的默认位置。
为了解决这个问题,我尝试使用 onSaveInstanceState(Bundle outState) 和 onCreate() 方法来实施适当的更正。然而,在调试过程中,我注意到 onCreate 中 saveInstanceState 不为 null 的代码部分永远不会到达,这让我的尝试显得徒劳。
这是我的 homefragment.java 类,也许我不明白 Bundle outState 和 Bundle savingInstanceState 之间的关系如何工作:
package com.seaguard.ui.home;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import com.seaguard.databinding.FragmentHomeBinding;
import org.osmdroid.api.IGeoPoint;
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapController;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider;
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay;
public class HomeFragment extends Fragment {
private FragmentHomeBinding binding;
private MapView map;
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if(savedInstanceState == null) {
System.out.println("BBB");
HomeViewModel homeViewModel = new ViewModelProvider(requireActivity()).get(HomeViewModel.class);
binding = FragmentHomeBinding.inflate(inflater, container, false);
View root = binding.getRoot();
// Map
map = binding.map;
map.setTileSource(TileSourceFactory.MAPNIK);
map.setBuiltInZoomControls(false);
map.setMultiTouchControls(true);
MapController mapController = (MapController) map.getController();
mapController.setCenter(new GeoPoint(41.8902, 12.4922)); // Rome
mapController.setZoom(16);
homeViewModel.setCallBack(() -> {
//provider.addLocationSource(LocationManager.NETWORK_PROVIDER);
MyLocationNewOverlay location = new MyLocationNewOverlay(new GpsMyLocationProvider(map.getContext()), map);
location.enableMyLocation();
map.getOverlays().add(location);
location.runOnFirstFix(() -> {
requireActivity().runOnUiThread(() -> map.getController().animateTo(location.getMyLocation()));
});
return location;
});
if (homeViewModel.permissionsRequested()) homeViewModel.setLocation();
return root;
}else{
System.out.println("AAAA");
View root = binding.getRoot();
double latitude = savedInstanceState.getDouble("latitude", 41.8902);
double longitude = savedInstanceState.getDouble("longitude", 12.4922);
int zoom_level = savedInstanceState.getInt("zoom_level", 16);
float map_orientation = savedInstanceState.getFloat("map_orientation", 0);
GeoPoint restoredCenter = new GeoPoint(latitude, longitude);
map.getController().setCenter(restoredCenter);
map.getController().setZoom(zoom_level);
map.setMapOrientation(map_orientation);
return root;
}
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
IGeoPoint center = map.getMapCenter();
outState.putDouble("latitude", center.getLatitudeE6() / 1e6);
outState.putDouble("longitude", center.getLongitudeE6() / 1e6);
outState.putInt("zoom_level", map.getZoomLevel());
outState.putFloat("map_orientation", map.getMapOrientation());
}
}
请注意,我使用这些 println 进行调试,似乎 AAA 永远不会在 logcat 中打印,因此代码永远不会被执行
我认为现在你可以尝试通过共享偏好来做到这一点,例如:-
//设置数据
SharedPreferences data = getSharedPreferences("MapData", MODE_PRIVATE);
SharedPreferences.Editor data_editor =data.edit();
//putting double in string as it does not store double value
data_editor.putString("latitude", String.valueOf(data1 / 1e6));
data_editor.putString("longitude", String.valueOf(data2 / 1e6));
data_editor.putInt("zoom_level", map.getZoomLevel());
data_editor.putFloat("map_orientation", map.getMapOrientation());
data_editor.apply();
//获取数据
SharedPreferences data = getSharedPreferences("MapData", MODE_PRIVATE);
lat= Double.valueOf(data.getString("latitude","0.0"));
lon= Double.valueOf(data.getString("longitude","0.0"));
//do it for others too
如果获得数据则加载地图
每次打开应用程序时请务必重置数据
SharedPreferences data = getSharedPreferences("MapData", MODE_PRIVATE);
SharedPreferences.Editor data_editor =data.edit();
data_editor.clear();
data_editor.commit();
其他虎钳它将加载上次保存的旧数据 完成后您还可以清除数据