【问题标题】:How to retain a map view inside a fragment?如何在片段中保留地图视图?
【发布时间】:2014-10-13 05:53:06
【问题描述】:

我有一个用例,其中列表和地图视图共享完全相同的代码库并显示相同的数据。所以我不能通过使用 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();
    }
}

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

【问题讨论】:

    标签: android android-fragments android-mapview


    【解决方案1】:

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

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

    mapView.getMap().addMarker(MyMarkerOptions);
    

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

    Here is another full example 使用Parcelable LatLng 指向持久化Markers

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


    OP 说明:

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

    【讨论】:

    • 我假设我必须删除 setRetainInstance 因为 onSaveInstanceState 不会被调用?
    • @artworkadshi 很酷,很高兴您找到了合适的解决方案。这个问题实际上是众所周知的,不幸的是没有直接的解决方案code.google.com/p/gmaps-api-issues/issues/detail?id=4650 除了我在这里建议的解决方案的变体。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-27
    • 1970-01-01
    • 2012-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-24
    相关资源
    最近更新 更多