配置更改时如何在地图片段上保留标记?

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">

(来自 Handling Runtime Changes

这样,当方向或屏幕尺寸发生变化时,您的 Activity 不会重新创建。如果你有 landscape/portrait.

的覆盖,你将不得不自己处理诸如布局切换之类的事情

似乎在保存地图的片段上调用 ​​setRetainInstance(true); 通过方向更改等保留地图上的所有内容,而不必担心保存和恢复状态。