如何在旋转设备(纵向/横向)后保留/重新绑定MapFragment上的事件侦听器?

时间:2017-04-03 19:22:00

标签: c# android xamarin event-listener mapfragment

我正在使用Xamarin(版本7.1)开发Android应用程序。它显示为地图并绘制PolyLines,在OnCameraIdle()中执行此操作。

MapFragment中以编程方式生成OnCreate。我通过GoogleMapOnResume中获取GetMapAsync并在OnMapReady中绑定了听众。
它们工作正常,但仅限于开始。一旦设备旋转(纵向 - >横向或反之亦然),相机移动不会再触发听众。
然而,地图有效 - 我(用户)仍然可以很好地移动相机。我(应用程序)再也无法使用它了。

这是裸代码,只有地图创建和处理。其他所有(实际绘图)都被删除了:

public class MapActivity : Activity, IOnMapReadyCallback, 
    GoogleMap.IOnCameraIdleListener, GoogleMap.IOnCameraMoveStartedListener
{
    private GoogleMap _map;
    private MapFragment _mapFragment;

    private void InitializeMap()
    {
        _mapFragment = MapFragment.NewInstance();
        var tx = FragmentManager.BeginTransaction();
        tx.Add(Resource.Id.map_placeholder, _mapFragment);
        tx.Commit();
    }

    private void SetMapListeners()
    {
        Log.Debug("MyApp/ Map", "SetMapListeners");
        _map.SetOnCameraIdleListener(this);
        _map.SetOnCameraMoveStartedListener(this);
    }

    /* Activity */

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        Log.Debug("MyApp / Map", "OnCreate");
        SetContentView(Resource.Layout.Map);
        InitializeMap();
    }

    protected override void OnStart()
    {
        base.OnStart();
        Log.Debug("MyApp / Map", "OnStart");
    }

    protected override void OnResume()
    {
        base.OnResume();
        if (_map == null)
            _mapFragment.GetMapAsync(this);
        Log.Debug("MyApp / Map", "OnResume");
    }

    protected override void OnPause()
    {
        base.OnPause();
        Log.Debug("MyApp / Map", "OnPause");
    }

    protected override void OnStop()
    {
        base.OnStop();
        Log.Debug("MyApp / Map", "OnStop");
    }

    protected override void OnDestroy()
    {
        base.OnStop();
        Log.Debug("MyApp/ Map", "OnDestroy");
    }


    /* IOnMapReadyCallback */   

    public void OnMapReady(GoogleMap googleMap)
    {
        Log.Debug("MyApp / Map", "Map is ready!");
        _map = googleMap;       
        SetMapListeners();
    }


    /* IOnCameraIdleListener */

    public void OnCameraIdle()
    {
        Log.Debug("MyApp / Map", "Camera is idle.");
        // Drawing routine is called here
    }


    /* IOnCameraMoveStartedListener */

    public void OnCameraMoveStarted(int reason)
    {
        Log.Debug("MyApp / Map", "Camera move started.");
    }
}

正如您在以下日志摘录中看到的那样,侦听器在开始时工作,但是一旦设备旋转(至少)一次,它们就会消失。
我还尝试在生命周期中调用SetMapListeners一次,第一次调用OnMapReady,但这并没有改变任何内容。

04-03 20:29:06.486 D/MyApp / Map( 7446): OnCreate
04-03 20:29:06.688 I/Google Maps Android API( 7446): Google Play services client version: 10084000
04-03 20:29:06.695 I/Google Maps Android API( 7446): Google Play services package version: 10298438
04-03 20:29:07.394 D/MyApp / Map( 7446): OnStart
04-03 20:29:07.399 D/MyApp / Map( 7446): OnResume
04-03 20:29:07.432 D/MyApp / Map( 7446): Map is ready!
04-03 20:29:07.438 D/MyApp / Map( 7446): SetMapListeners
04-03 20:29:07.568 D/MyApp / Map( 7446): Camera is idle.
04-03 20:29:09.231 D/MyApp / Map( 7446): Camera move started.
04-03 20:29:09.590 D/MyApp / Map( 7446): Camera is idle.
04-03 20:29:12.350 D/MyApp / Map( 7446): Camera move started.
04-03 20:29:12.751 D/MyApp / Map( 7446): Camera is idle.

## Listeners are responding, now rotating the device.

04-03 20:29:15.503 D/MyApp / Map( 7446): OnPause
04-03 20:29:15.508 D/MyApp / Map( 7446): OnStop
04-03 20:29:15.572 D/MyApp / Map( 7446): OnDestroy
04-03 20:29:15.595 I/Google Maps Android API( 7446): Google Play services package version: 10298438
04-03 20:29:15.596 D/MyApp / Map( 7446): OnCreate
04-03 20:29:15.628 I/Google Maps Android API( 7446): Google Play services package version: 10298438
04-03 20:29:15.655 D/MyApp / Map( 7446): OnStart
04-03 20:29:15.655 D/MyApp / Map( 7446): OnResume
04-03 20:29:15.690 D/MyApp / Map( 7446): Map is ready!
04-03 20:29:15.691 D/MyApp / Map( 7446): SetMapListeners

## Map is rotated, camera position was preserved. 
## Now moving the camera, but no listeners are responding.

04-03 20:29:24.436 D/MyApp / Map( 7446): OnPause
04-03 20:29:31.288 D/MyApp / Map( 7446): OnStop
04-03 20:29:31.359 D/MyApp / Map( 7446): OnDestroy

这里有趣的是,当我切换回上一个活动并再次打开地图时,它会重新开始并再次运行。但是,正如您在日志中看到的那样,在旋转设备时,活动也会被破坏并重新创建。据我所知,片段不是,所以也许是这样的暗示。我不知道。

我还尝试删除OnDestroy中的听众(通过设置null),但这也没有改变任何内容。

你知道我可能做错了什么吗?

4 个答案:

答案 0 :(得分:5)

尝试将InitializeMap()调用放入OnCreateView()方法的覆盖中,而不是OnCreate()

答案 1 :(得分:5)

默认情况下,当屏幕旋转时,您的Activity将被终止并重新启动。要确保没有数据丢失,您需要使用生命周期方法正确保存和恢复数据。请参阅SavingPersistentStatesavedInstanceState并按照此Android Developer Documentation希望今年五月有所帮助。!

答案 2 :(得分:4)

我有类似的问题,因为我们将MapFragment嵌套在另一个Fragment中,所以我们每次都必须重新添加MapFragment。由于您已将其直接嵌入到Activity中,因此@App Pack也可以正常工作,但无论如何我都会粘贴代码。

iuptest(.exe)

并且请:函数应该从小写开始!!!

答案 3 :(得分:2)

尝试检查savedInstanceState以查看您的Activity是第一次构建还是只是返回它。你似乎在每次通话时重叠片段。