配置更改时如何在地图片段上保留标记?
How to keep markers on a map fragment when configuration changes?
我的 Main Activity 中有一个地图片段,在我的 onMapReady 中添加了 300 个标记。标记分为5类,每类保存在一个List category1(2,3,4,5) = new ArrayList中。我有一个按钮,可以根据警报对话框中的用户选项将标记设置为可见或不可见,从而按类别过滤标记。
for (Marker marker : category1) {
marker.setVisible(true);.....
一切正常,直到屏幕配置发生变化。
我发现保持可见标记旋转的一种解决方案是在我的 onCreate
中添加
if (savedInstanceState == null) {
mapFragment.setRetainInstance(true);}
这适用于保留当前选择,但是当我再次尝试过滤时没有任何变化。地图片段的状态与我在配置更改之前过滤的标记保持一致。
另一方面,如果我没有使用 mapFragment.setRetainInstance(true);每次配置更改时,所有标记都会再次添加到片段上,过滤再次起作用,但我每次都必须重新过滤。
如何一次性添加所有标记,然后hide/show根据类别筛选,保留屏幕旋转之间可见的标记,然后从上次状态开始再次筛选它们?
更新
这是我的(我试图只添加相关代码)
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");
您可以在清单中自行处理方向更改:
<activity android:name=".MyActivity"
android:configChanges="orientation|screenSize"
android:label="@string/app_name">
这样,当方向或屏幕尺寸发生变化时,您的 Activity
不会重新创建。如果你有 landscape/portrait.
的覆盖,你将不得不自己处理诸如布局切换之类的事情
似乎在保存地图的片段上调用 setRetainInstance(true);
通过方向更改等保留地图上的所有内容,而不必担心保存和恢复状态。
我的 Main Activity 中有一个地图片段,在我的 onMapReady 中添加了 300 个标记。标记分为5类,每类保存在一个List category1(2,3,4,5) = new ArrayList中。我有一个按钮,可以根据警报对话框中的用户选项将标记设置为可见或不可见,从而按类别过滤标记。
for (Marker marker : category1) {
marker.setVisible(true);.....
一切正常,直到屏幕配置发生变化。 我发现保持可见标记旋转的一种解决方案是在我的 onCreate
中添加if (savedInstanceState == null) {
mapFragment.setRetainInstance(true);}
这适用于保留当前选择,但是当我再次尝试过滤时没有任何变化。地图片段的状态与我在配置更改之前过滤的标记保持一致。
另一方面,如果我没有使用 mapFragment.setRetainInstance(true);每次配置更改时,所有标记都会再次添加到片段上,过滤再次起作用,但我每次都必须重新过滤。
如何一次性添加所有标记,然后hide/show根据类别筛选,保留屏幕旋转之间可见的标记,然后从上次状态开始再次筛选它们?
更新
这是我的(我试图只添加相关代码)
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");
您可以在清单中自行处理方向更改:
<activity android:name=".MyActivity"
android:configChanges="orientation|screenSize"
android:label="@string/app_name">
这样,当方向或屏幕尺寸发生变化时,您的 Activity
不会重新创建。如果你有 landscape/portrait.
似乎在保存地图的片段上调用 setRetainInstance(true);
通过方向更改等保留地图上的所有内容,而不必担心保存和恢复状态。