首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Xamarin Forms Android: map.Pins.Clear()

Xamarin Forms Android: map.Pins.Clear()
EN

Stack Overflow用户
提问于 2020-03-23 03:23:21
回答 1查看 408关注 0票数 1

我和我的开发团队在我们的Xamarin项目的Android版本上遇到了一个问题。问题是这样的:应用程序使用一个可观察的对象集合,并以列表视图和带有代表对象的引脚的映射视图的形式表示这些对象。在地图视图中,我们的代码被设计为订阅消息中心调用,该调用定期更新API (项目的其他部分)中可观察到的对象集合。我们面临的问题是,当我们在消息传递中心代码块中调用PlotPins方法时,应用程序应该首先检索更新的列表,然后访问该列表来绘制地图上的图钉。每次收到更新时,应用程序将清除地图中的所有引脚,然后根据更新的列表重新绘制引脚(我们知道,这是一个临时的解决方案)。但是,引脚从未更新过。通过使用调试器,我们发现一旦调用了PlotPins()中的PlotPins(),应用程序跳到RequestUpdatedListAsync方法的末尾(该方法定期发生以检索更新的列表并触发消息传递中心),然后停止。

我们的解决方案适用于我们的GTK构建,并按预期在地图上清除和重新绘制引脚,因此这似乎是Android特有的问题。

任何帮助都将不胜感激,谢谢。

有关守则如下:

信息传递中心:

代码语言:javascript
复制
MessagingCenter.Subscribe<object, ObservableCollection<MyObject>>(Application.Current, Constants.ListUpdateContract, (sender, newList) =>
            { 
                //update list
                listUpdater.UpdateList(newList);
                //call method to plot pins again
                PlotPins(map);
            });

PLOTPINS:

代码语言:javascript
复制
private void PlotPins(Map map)
        {
            map.Pins.Clear();
            foreach (MyObject in MyObjects)
            {
                var pin = new Pin
                {
                    Label = MyObject.ID,
                    Address = "Latitude: " + MyObject.Latitude + " " + "Longitude: " + MyObject.Longitude,
                    Type = PinType.Place,
                    Position = new Position(Convert.ToDouble(MyObject.Latitude), Convert.ToDouble(MyObject.Longitude))
                };
                //event handler for when user clicks on pin's info window
                pin.InfoWindowClicked += async (s, args) =>
                {
                    //opens up detail page for pin associated with myObject
                    await Navigation.PushAsync(new DetailPage(MyObject));
                };

                map.Pins.Add(pin);
            }

        }

请求更新清单ASYNC:

代码语言:javascript
复制
public static async System.Threading.Tasks.Task<bool> RequestUpdatedListAsync()
        {
            if (!_tokenIsGood)
                return false;
            var success = false;
            var response = new HttpResponseMessage();


            try
            {
                response = await _client.GetAsync(Constants. MyObjectDisplayUrl);
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine("Error requesting updated list.");
                System.Diagnostics.Debug.WriteLine(e.Message);
                System.Diagnostics.Debug.WriteLine(e.StackTrace);
                return success;
            }

            response.EnsureSuccessStatusCode();
            success = true;
            var responseBody = await response.Content.ReadAsStringAsync();

            // Update list
            MyObjects.Clear();
            MyObjects = JsonConvert.DeserializeObject<ObservableCollection< MyObject >>(responseBody);

            //Alert subscribed ViewModels to update list
            MessagingCenter.Send<object, ObservableCollection< MyObject >>(Application.Current, Constants.ListUpdateContract, units);


            return success;
        }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-24 01:50:18

因为maps.Pins与UI相关,所以它必须在主UI线程中运行。

MessagingCenter并不总是在主线程中发布/订阅。

因此,要解决此问题,请在主线程中调用maps.Pins.Clear()

代码语言:javascript
复制
Device.BeginInvokeOnMainThread(()=> maps.Pins.Clear());

Credits:@shanranm用于提到MessagingCenter对使用主线程的限制。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60807573

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档