I have a map fragment in my Main Activity that on my onMapReady I am adding let's say 300 markers. The markers are divided into 5 categories, each category saved in a List category1(2,3,4,5) = new ArrayList. I have a button that filters the markers by category by setting them visible or not according to the users options from an alert dialog.
for (Marker marker : category1) {
marker.setVisible(true);.....
Everything works exactly as it should until the screen configuration changes. One solution that I found to keep the visible markers on rotation was to add in my onCreate
if (savedInstanceState == null) {
mapFragment.setRetainInstance(true);}
This works for keeping the current selection but then when I try to filter again nothing changes. The state of the map fragment remains with the markers that I filtered before the configuration changed.
On the other hand if I am not using the mapFragment.setRetainInstance(true); each time the configuration changes ALL the markers are added again on the fragment, filtering works again but i have to re filter each time.
How can I add all the markers once, and then hide/show them according to the category filter, keep the visible ones between screen rotation and filter them again starting from the last state they were?
UPDATE
Here is what I have (I tried to add only the relevant code)
Boolean mSetCameraPosition;
Boolean initialMarkers;
Boolean checkBox1Checked, checkBox2Checked, checkBox3Checked, checkBox4Checked, checkBox5Checked;
private int mapTypeSelected;
CheckBox cbAllDay, cbBefore12, cbBetween1216, cbBetween1620, ccbAfter20;
AlertDialog dialog;
List<Marker> firstCategoryList = new ArrayList<>();
List<Marker> secondCategoryList = new ArrayList<>();
List<Marker> thirdCategoryList = new ArrayList<>();
List<Marker> fourthCategoryList = new ArrayList<>();
List<Marker> fifthCategoryList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkLocationPermission();
}
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
if (savedInstanceState == null) {
mapTypeSelected = GoogleMap.MAP_TYPE_NORMAL;
mSetCameraPosition = true;
mapFragment.setRetainInstance(true);
initialMarkers = true;
} else {
mapTypeSelected = savedInstanceState.getInt("the_map_type", GoogleMap.MAP_TYPE_NORMAL);
mSetCameraPosition = false;
initialMarkers = false;
checkBox1Checked = savedInstanceState.getBoolean("checkBox1");
checkBox2Checked = savedInstanceState.getBoolean("checkBox2");
checkBox3Checked = savedInstanceState.getBoolean("checkBox3");
checkBox4Checked = savedInstanceState.getBoolean("checkBox4");
checkBox5Checked = savedInstanceState.getBoolean("checkBox5");
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (mSetCameraPosition) {
initialLocation(TOULOUSE_LAT, TOULOUSE_LNG, 12);
}
mMap.setMapType(mapTypeSelected);
if (initialMarkers) {
addMarkers2Map();
}
public void addMarkers2Map() {
// Markers location
LatLng marker1 = new LatLng(43.607044, 1.450307);
LatLng marker2= new LatLng(43.571505, 1.417759);
LatLng marker3= new LatLng(43.607469, 1.447162);
LatLng marker4= new LatLng(43.600723, 1.455917);
LatLng marker5= new LatLng(43.604892, 1.476562);
LatLng marker6= new LatLng(43.604496, 1.474924);
LatLng marker7= new LatLng(43.604781, 1.474502);
// Markers All day long
firstCategoryList.add(mMap.addMarker(new MarkerOptions().position(marker1).title("First Place ").icon(BitmapDescriptorFactory.fromResource(R.drawable.beer_marker)).snippet("HH: 8.30 - 22.30")));
// Markers Before 12 PM
secondCategoryList.add(mMap.addMarker(new MarkerOptions().position(marker2).title("Second Place").icon(BitmapDescriptorFactory.fromResource(R.drawable.beer_marker)).snippet("HH: 10.30 - 11.30")));
// Markers Between 12-16
thirdCategoryList.add(mMap.addMarker(new MarkerOptions().position(marker3).title("Third Place").icon(BitmapDescriptorFactory.fromResource(R.drawable.beer_marker)).snippet("HH: 15.30 - 16.30")));
thirdCategoryList.add(mMap.addMarker(new MarkerOptions().position(marker4).title("Fourth Place").icon(BitmapDescriptorFactory.fromResource(R.drawable.beer_marker)).snippet("HH: 15.00 - 16.00")));
// Markers Between 16-20
fourthCategoryList.add(mMap.addMarker(new MarkerOptions().position(marker5).title("Fifth Place").icon(BitmapDescriptorFactory.fromResource(R.drawable.beer_marker)).snippet("HH: 15.30 - 16.30")));
fourthCategoryList.add(mMap.addMarker(new MarkerOptions().position(marker6).title("Sixth Place").icon(BitmapDescriptorFactory.fromResource(R.drawable.beer_marker)).snippet("HH: 16.30 - 17.30")));
fourthCategoryList.add(mMap.addMarker(new MarkerOptions().position(marker7).title("Seventh Place").icon(BitmapDescriptorFactory.fromResource(R.drawable.beer_marker)).snippet("HH: 18.30 - 19.30")));
fourthCategoryList.add(mMap.addMarker(new MarkerOptions().position(marker8).title("Eighth Place").icon(BitmapDescriptorFactory.fromResource(R.drawable.beer_marker)).snippet("HH: 17.30 - 18.30\nHH:21.30 - 22.30")));
// Markers After 20
fifthCategoryList.add(mMap.addMarker(new MarkerOptions().position(marker8).title("Eighth Place").icon(BitmapDescriptorFactory.fromResource(R.drawable.beer_marker)).snippet("HH: 17.30 - 18.30\nHH:21.30 - 22.30")));
fifthCategoryList.add(mMap.addMarker(new MarkerOptions().position(marker1).title("First Place").icon(BitmapDescriptorFactory.fromResource(R.drawable.beer_marker)).snippet("HH: 8.30 - 22.30")));
public void filterTheMarkers(View view) {
if (dialog == null){
AlertDialog.Builder builder;
builder = new AlertDialog.Builder(this);
LayoutInflater inflater = this.getLayoutInflater();
@SuppressLint("InflateParams") View checkBoxView = inflater.inflate(R.layout.markers_filtering, null);
builder.setView(checkBoxView);
cbAllDay = (CheckBox) checkBoxView.findViewById(R.id.checkBox1);
if (checkBox1Checked != null) {
cbAllDay.setChecked(checkBox1Checked);
}
cbBefore12 = (CheckBox) checkBoxView.findViewById(R.id.checkBox2);
if (checkBox2Checked != null) {
cbBefore12.setChecked(checkBox2Checked);
}
cbBetween1216 = (CheckBox) checkBoxView.findViewById(R.id.checkBox3);
if (checkBox3Checked != null) {
cbBetween1216.setChecked(checkBox3Checked);
}
cbBetween1620 = (CheckBox) checkBoxView.findViewById(R.id.checkBox4);
if (checkBox4Checked != null) {
cbBetween1620.setChecked(checkBox4Checked);
}
ccbAfter20 = (CheckBox) checkBoxView.findViewById(R.id.checkBox5);
if (checkBox5Checked != null) {
ccbAfter20.setChecked(checkBox5Checked);
}
dialog = builder.create();
}
dialog.show();
}
public void displaySelectedMarkers(View view) {
dialog.dismiss();
Log.i("TAG", "All Day " + cbAllDay.isChecked() + " Before 12 " + cbBefore12.isChecked() + " Between 12-16 " + cbBetween1216.isChecked() + " Between 16-20" + cbBetween1620.isChecked() + " After 20 " + ccbAfter20.isChecked());
//according these check boxes status execute your code to show/hide markers
if (cbAllDay.isChecked() && cbBefore12.isChecked() && cbBetween1216.isChecked() && cbBetween1620.isChecked() && ccbAfter20.isChecked()) {
// show all markers
for (Marker marker : firstCategoryList) {
marker.setVisible(true);
}
for (Marker marker : secondCategoryList) {
marker.setVisible(true);
}
for (Marker marker : thirdCategoryList) {
marker.setVisible(true);
}
for (Marker marker : fourthCategoryList) {
marker.setVisible(true);
}
for (Marker marker : fifthCategoryList) {
marker.setVisible(true);
}
} else if (cbAllDay.isChecked() && !cbBefore12.isChecked() && !cbBetween1216.isChecked() && !cbBetween1620.isChecked() && !ccbAfter20.isChecked()) {
// show only All Day Markers
for (Marker marker : firstCategoryList) {
marker.setVisible(true);
}
for (Marker marker : secondCategoryList) {
marker.setVisible(false);
}
for (Marker marker : thirdCategoryList) {
marker.setVisible(false);
}
for (Marker marker : fourthCategoryList) {
marker.setVisible(false);
}
for (Marker marker : fifthCategoryList) {
marker.setVisible(false);
}
}
//....and it goes like this for a while until I finish all the possibilities
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("the_map_type", mapTypeSelected);
outState.putBoolean("checkBox1", cbAllDay.isChecked());
outState.putBoolean("checkBox2", cbBefore12.isChecked());
outState.putBoolean("checkBox3", cbBetween1216.isChecked());
outState.putBoolean("checkBox4", cbBetween1620.isChecked());
outState.putBoolean("checkBox5", ccbAfter20.isChecked());
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
savedInstanceState.get("the_map_type");
checkBox1Checked = savedInstanceState.getBoolean("checkBox1");
checkBox2Checked = savedInstanceState.getBoolean("checkBox2");
checkBox3Checked = savedInstanceState.getBoolean("checkBox3");
checkBox4Checked = savedInstanceState.getBoolean("checkBox4");
checkBox5Checked = savedInstanceState.getBoolean("checkBox5");
You could handle orientation changes yourself in your manifest:
<activity android:name=".MyActivity"
android:configChanges="orientation|screenSize"
android:label="@string/app_name">
(from Handling Runtime Changes)
That way, your Activity
isn't recreated when the orientation or screen size changes. You'll have to handle things like layout switching yourself though if you have overrides for landscape/portrait.