如何在片段内保留地图视图?

时间:2014-10-13 05:53:06

标签: android android-fragments android-mapview

我有一个用例,其中列表和地图视图共享完全相同的代码库并显示相同的数据。所以我不能通过使用ListFragment和MapFragment作为父级来分离它们。

所以我创建了一个包含两个视图的片段:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="invisible"/>

    <com.google.android.gms.maps.MapView
        android:id="@+id/mapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>

用户可以在列表和地图视图之间切换。尽管地图视图无法在配置更改中保留其标记,但这仍然很有效。旋转屏幕时,地图视图将获得其没有标记且没有缩放的初始状态。之前添加的所有标记都消失了。当我使用MapFragment时,我没有遇到这个问题,它有点保留了自己。

剥离代码:

public class ListAndMapFragment extends Fragment {

    private MapView mapView;

    public ListAndMapFragment() {}

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
    }

     @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle arguments) {
        super.onCreateView(inflater, container, arguments);
        View root = inflater.inflate(R.layout.fragment_pillar_list, container, false);
        mapView = (MapView) root.findViewById(R.id.mapView);

        if (arguments == null) {
            mapView.onCreate(null);
            MapsInitializer.initialize(this.getActivity());
        }

        return root;
    }

    private GoogleMap getMap() {
        return mapView.getMap();
    }

    @Override
    public void onResume() {
        mapView.onResume();
        super.onResume();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mapView.onLowMemory();
    }
}

有任何想法如何解决这个问题?一种解决方案是替换所有标记。但是,我想知道是否有其他方法。

1 个答案:

答案 0 :(得分:3)

Marker对象无法通过配置更改保留,因为它不会实现ParcelableSerializable接口。

但是,您可以保留MarkerOptions对象,因为它是Parcelable,然后从中重新创建Marker。您可以为每个MarkerOptions设置类型为Marker的类字段,然后在配置更改时重新填充地图(例如在onSaveInstanceState中):

mapView.getMap().addMarker(MyMarkerOptions);

另一种方法是将您的Marker保存在HashMap中,并在配置更改时重复使用它们。

Here is another full example使用Parcelable LatLng点来保留Markers

该示例在添加标记时也起作用,它还将相应的坐标添加到ArrayList作为LatLng对象。然后,在配置更改时,ArrayList会保存到Bundle中的onSaveInstanceState对象,LatLng对象会在onCreate中被检索。


OP注:

所以我选择了解决方案来实施onSaveInstanceState并放弃setRetainInstance(true)。好处是我可以自己保留地图。然而,缺点是必须在每次配置更改时完全初始化地图,这使得app在例如1或2秒内变慢。屏幕旋转。但我对此很好。