我有一个类“MainActivity”,它调用不同的片段,特别是一个显示名为 MapsFragment 的GoogleMap的片段。 当第一次调用此片段时,我有一些标记(每次 timeToRefresh 刷新。 startDrawingBomb()从 MainActivity中调用 class)当用户不改变为另一个片段时,一切都很完美。
当用户要求移动到其他片段时,我将之前创建的 MapsFragment 保存在 MainActivity 的backStack中(以便稍后检索)
问题发生在我第二次调用 MapsFragment 时,片段显示的是地图,但不是之前我添加的所有标记。 我想这是因为MapView和 MapsFragment 创建的GoogleMap与以前不一样。
我的问题是:如何轻松检索我之前绘制的地图?或者我必须停止所有线程(例如onPause()),创建一个新的 MapsFragment ,获取一个新的MapView,一个新的GoogleMap对象并再次应用所有以前的线程?
这是 MapsFragment 的一部分:
public class MapsFragment extends Fragment implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener, LocationListener {
private LocationRequest mLocationRequest;
private GoogleApiClient mGoogleApiClient;
private OnMessageListener mCallback;
private GoogleMap _googleMap;
private MapView mMapView;
private ArrayList<Marker> markerArrayListScout = new ArrayList<>();
private ArrayList<Circle> markerArrayListBomb= new ArrayList<>();
private ArrayList<String> idToCircleId = new ArrayList<>();
private ArrayList<Integer> idArray = new ArrayList<>();
private boolean isfirstLocation = true;
boolean mustBeScoutLocationEnabled;
boolean mustDrawCircle;
public MapsFragment(){
super();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v("MAPS_FRAGMENT","onCreate() called");
mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.v("MAPS_FRAGMENT","onCreateView() called");
View rootView = inflater.inflate(R.layout.map, container, false);
mMapView = (MapView) rootView.findViewById(R.id.mapView);
mMapView.onCreate(savedInstanceState);
mMapView.onResume(); // needed to get the map to display immediately
try {
MapsInitializer.initialize(getActivity().getApplicationContext());
} catch (Exception e) {
e.printStackTrace();
}
mMapView.getMapAsync(this);
return rootView;
}
@Override
public void onResume() {
super.onResume();
mMapView.onResume();
}
@Override
public void onPause() {
super.onPause();
mMapView.onPause();
}
@Override
public void onDestroy() {
super.onDestroy();
mMapView.onDestroy();
}
@Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}
@Override
public void onMapReady(GoogleMap googleMap) {
Log.v("MAPS_FRAGMENT","onMapReady() called");
_googleMap = googleMap;
_googleMap.setMyLocationEnabled(true);
}
@Override
public void onConnected(@Nullable Bundle bundle) {
Log.v("Location","onConnected");
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(1000); // Update location every second
//Execute location service call if user has explicitly granted ACCESS_FINE_LOCATION..
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
@Override
public void onConnectionSuspended(int i) {
Log.v("Location","onConnectionSuspended");
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Log.v("Location","onConnectionFailed");
}
@Override
public void onLocationChanged(Location location) {
Log.v("Location","location : " + location.toString());
// Add a marker and move the camera
if(isfirstLocation) {
LatLng currentLat = new LatLng(location.getLatitude(), location.getLongitude());
_googleMap.moveCamera(CameraUpdateFactory.newLatLng(currentLat));
_googleMap.moveCamera(CameraUpdateFactory.zoomTo(19));
isfirstLocation = false;
}
//if(mCallback != null)
mCallback.onUpdateLocation(location.getLatitude(),location.getLongitude());
}
/**
* Draw Bomb and update its view all the timeToRefresh milliseconds.
* @param timeToRefresh the time in milliseconds which the marker needs to refresh
* @param id the id of the current bomb we need to work with
*/
public void startDrawingBomb(final int timeToRefresh,final int id){
mustDrawCircle = true;
Log.v("JOSE","passe1");
final Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
while (mustDrawCircle) {
Log.v("JOSE","update bomb");
mCallback.updateBombs();
//Log.v("JOSE","bomb updated ?");
Thread.sleep(timeToRefresh);
// This method is called from the MainActivity
final CircleOptions circleOptions = mCallback.drawBombCircle(id);
final String idToCompare = getIdCircle(id);
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
boolean isCenterSet = false;
if (circleOptions != null) {
Log.v("JOSE","size marker : " +markerArrayListBomb.size());
for(int i=0;i<markerArrayListBomb.size();i++){
Log.v("JOSE","Id to compare : " +idToCompare);
Log.v("JOSE","Id markearray : " +markerArrayListBomb.get(i).getId());
if((markerArrayListBomb.get(i).getId()).equals(idToCompare)){
// si c'est la même chose, il suffit de updater
markerArrayListBomb.get(i).setCenter(circleOptions.getCenter());
markerArrayListBomb.get(i).setVisible(true);
isCenterSet = true;
}
}
// il faut creer une nouvelle bombe
if(!isCenterSet) {
Circle newCircle = _googleMap.addCircle(circleOptions);
markerArrayListBomb.add(newCircle);
newIdCircle(id, newCircle.getId());
//Log.v("JOSE", "New bomb drawn id : " + newCircle.getId());
}
}
}
});
}
String idToCompare = getIdCircle(id);
for(int i=0;i<markerArrayListBomb.size();i++){
if((markerArrayListBomb.get(i).getId()).equals(idToCompare)){
final int index = i;
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
markerArrayListBomb.get(index).setVisible(false);
}
});
}
}
}
catch (InterruptedException e){
e.printStackTrace();
}
}
});
thread.start();
}
public void cancelDrawingBomb(){mustDrawCircle = false;}
// Container Activity must implement this interface
public interface OnMessageListener {
public void onUpdateLocation(double lat,double lon);
public void getAllOtherScoutsLocation();
public void updateBombs();
public CircleOptions drawBombCircle(int id);
}
/**
*
* @param id de la bombe dans la classe Bomb
* @return le cercle créé associé. Sinon, return null
*/
private String getIdCircle(int id){
if(idArray.size() == 0)
return null;
for(int i=0 ; i<idArray.size();i++){
if(idArray.get(i) == id)
return idToCircleId.get(i);
}
return null;
}
/**
* Si une bombe est supprimée, il faut appeler cette méthode
* @param id
*/
private void removeIdCircle(int id){
for(int i=0 ; i<idArray.size();i++){
if(idArray.get(i) == id) {
idToCircleId.remove(i);
idArray.remove(i);
}
}
}
/**
* A appeler à chaque fois u'une bombe est créée
* @param id l'id de la classe BOMB
* @param ids l'id créé grâce à la classe Circle de google
*/
private void newIdCircle(int id,String ids){
idToCircleId.add(ids);
idArray.add(id);
}
}
这就是我第二次打电话给 MapsFragment :
if (id == R.id.map) {
if(fragmentManager.findFragmentByTag(MAPS_FRAGMENT) != null){
MapsFragment fragment = (MapsFragment)fragmentManager.findFragmentByTag(MAPS_FRAGMENT);
fragmentManager.beginTransaction().replace(R.id.frame_container, fragment,MAPS_FRAGMENT).addToBackStack(MAPS_FRAGMENT).commit();
}
}
非常感谢大家,抱歉我的英语不好。 如果您想了解更多信息或更好的解释,请不要犹豫告诉我!
答案 0 :(得分:0)
在MapFragment的Onpause()上实现save to bundle功能。然后在onCreateView()中始终检查您的包。
如果捆绑包是空的,那么它就是一个新的片段。如果捆绑包不为空,则表示它先前已创建。
希望这会有所帮助:
保存并恢复到捆绑:Saving Android Activity state using Save Instance State