frankiesardo / icepick

Android Instance State made easy
Eclipse Public License 1.0
3.75k stars 208 forks source link

Bundler that modifies object in get method #119

Open snorkel123 opened 6 years ago

snorkel123 commented 6 years ago

Problem Some objects whose state should be saved are constructed by other library. For instance, GoogleMap. Thus Bundler's get method's return value is not applicable here.

Proposal Alternative Bundler (MutatingBundler) that:

Proposal example

class MyMap extends MapFragment implements OnMapReadyCallback {

   @State(MapBundler.class) GoogleMap map;

   Bundle savedInstanceState;

   void onViewCreated(Bundle savedInstanceState) {
      this.savedInstanceState = savedInstanceState;
      getMapAsync(this);
   }

   void onMapReady(GoogleMap map) {
      this.map = map;
      IcePick.restoreInstanceState(this, this.savedInstanceState);
   }

   void onSaveInstanceState(Bundle outState) {
      IcePick.saveInstanceState(this, outState);
      super.onSaveInstanceState(outState);
   }

}

// MutatingBundler!
class MapBundler implements MutatingBundler<GoogleMap> {
   void put(String key, GoogleMap map, Bundle bundle) {

      CameraPosition position = map.getCameraPosition();

      bundle.putFloat(key + "zoom", position.zoom);
      bundle.putDouble(key + "lat", position.target.latitude);
      bundle.putDouble(key + "lon", position.target.longitude);
      bundle.putFloat(key + "tilt", position.tilt);
      bundle.putFloat(key + "bearing", position.bearing);

   }

   // <<<<<<<<<<<<<<<<<<< Here is the difference >>>>>>>>>>>>>>>>>>>
   // GoogleMap get(String key, Bundler bundle) {...} <--------- This is previous state
   void get(String key, @NonNull GoogleMap map, Bundle bundle) {

      float zoom = bundle.getFloat(key + "zoom");
      double lat = bundle.getDouble(key + "lat");
      double lon = bundle.getDouble(key + "lon");
      float tilt = bundle.getFloat(key + "tilt");
      float bearing = bundle.getFloat(key + "bearing");

      LatLng target = new LatLng(lat, lon);
      CameraPosition restoreCamPosition = new CameraPosition(target, zoom, tilt, bearing);
      map.moveCamera(CameraUpdateFactory.newCameraPosition(restoreCamPosition));
   }

}