从backstack

时间:2016-12-06 21:25:33

标签: android

我有一个类“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();
        }
    }

非常感谢大家,抱歉我的英语不好。 如果您想了解更多信息或更好的解释,请不要犹豫告诉我!

1 个答案:

答案 0 :(得分:0)

在MapFragment的Onpause()上实现save to bundle功能。然后在onCreateView()中始终检查您的包。

如果捆绑包是空的,那么它就是一个新的片段。如果捆绑包不为空,则表示它先前已创建。

希望这会有所帮助:

保存并恢复到捆绑:Saving Android Activity state using Save Instance State