Reputation: 759
I am using two fragment. One is a list fragment and the other one a map fragment.
The list shows list of places. When any item from the list is clicked the fragment is replaced and the place is shown on the map fragment with a marker.
The code that I am using when an item on the list is being pressed (in order to show the map fragment) is like this:
@Override
public void onPlace(Double lan, Double lat, String name) {
// Setting a LatLng variables according to the lan and lat that the
// function received
LatLng place = new LatLng(lan, lat);
// Getting the zoom by the user choice
SharedPreferences userPref = PreferenceManager.getDefaultSharedPreferences(this);
if (userPref != null) {
zooMao = Integer.parseInt(userPref.getString("zoomsize", "17"));
}
GoogleMapOptions options = new GoogleMapOptions();
options.camera(CameraPosition.fromLatLngZoom(place, zooMao));
options.mapType(GoogleMap.MAP_TYPE_SATELLITE);
Mapf mapFrag = Mapf.newInstance(place, name, options);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.phone_cont, mapFrag, "map");
ft.addToBackStack(null);
ft.commit();
}
As you can see I am using my own map fragment code - with the name -Mapf - and this is the code for it:
public class Mapf extends SupportMapFragment {
private LatLng position;
private Marker marker;
private String name;
// Creating an instance of the map fragment
public static Mapf newInstance(LatLng pos, String place, GoogleMapOptions option){
// Declaring an instance of the map object
Mapf fragment = new Mapf();
//Adding data to the fragment
// such as position, name and map options
Bundle args = new Bundle();
//obtained by decompiling google-play-services.jar
args.putParcelable("MapOptions", option);
fragment.name = place;
fragment.position = pos;
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = super.onCreateView(inflater, container, savedInstanceState);
initMap();
return v;
}
// This function adding marker and location name and position to the map
private void initMap(){
// If there's a marker - removing it
if (marker != null) {
marker.remove();
}
// Declaring icon for the marker
BitmapDescriptor icon = BitmapDescriptorFactory.fromResource(R.drawable.icon);
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(position);
markerOptions.title(name);
markerOptions.icon(icon);
marker = getMap().addMarker(markerOptions);
// in case there's no name for the place - no need in a marker
// using for the first loading of the map fragment
if(name.equals("")){
marker.remove();
}
}
}
Now the thing is when I see the map with the current place - all is fine!
But when I am changing the screen orientation of the device, the app is crashing, saying that the marker is missing the place position's.
So what can I do in order to show the right place when the screen orientation is being changed?
Thanks for any kind of help.
and here's the logcat
01-15 13:22:06.012: E/AndroidRuntime(1492): FATAL EXCEPTION: main
01-15 13:22:06.012: E/AndroidRuntime(1492): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.myplaces1/com.example.myplaces1.view.MainActivity}: java.lang.IllegalArgumentException: no position in marker options
01-15 13:22:06.012: E/AndroidRuntime(1492): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
Upvotes: 0
Views: 1520
Reputation: 41099
You error indicates:
java.lang.IllegalArgumentException: no position in marker options
The reason for that is that when you change orientation of the screen all the parameters you passed to your fragment are lost.
So what you need to do is:
public static Fragment create(String vid) {
VenueFragment fragment = new VenueFragment();
Bundle args = new Bundle();
args.putString(ARG_VENUEID, vid);
fragment.setArguments(args);
return fragment;
}
as you already did with your newInstance
method, but what you didn't do
is in onCreate
do this:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
CupsLog.i(TAG, "VenueFragment onCreate");
mVenueId = getArguments().getString(ARG_VENUEID);
}
basically your need to get the data you passed at instantiation and save it locally.
UPDATE: For your case of the LatLng do this, devide the LatLng object to two doubles:
public static Fragment create(double lat, double lng) {
VenueFragment fragment = new VenueFragment();
Bundle args = new Bundle();
args.putDouble(LAT, lat)
args.putDouble(LNG, lng)
fragment.setArguments(args);
return fragment;
}
and in onCreate
:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
CupsLog.i(TAG, "VenueFragment onCreate");
lat = getArguments().getDouble(LAT);
lng = getArguments().getDouble(LNG);
}
Upvotes: 3