.NET MAUI中Activity Indicator显示时机异常问题求助
解决ActivityIndicator延迟显示的问题
你的问题根源在于同步网络请求阻塞了UI线程。当你在按钮点击事件里执行WebClient.DownloadString这类同步方法时,整个UI线程会被卡住,无法立即更新ActivityIndicator的显示状态——直到所有同步操作(地图设置、网络请求、数据解析、TreeView绑定)全部完成,UI才会刷新,这就导致Indicator看起来是在数据加载完成后才出现。
改用异步操作释放UI线程,让UI能及时响应Indicator的显示指令,具体修改步骤如下:
1. 修改按钮点击事件为异步方法
在方法签名前添加async关键字,同时加入异常处理和按钮状态控制,避免重复点击:
async void btIndicatorOn_Clicked(System.Object sender, System.EventArgs e) { // 立即显示Indicator acIndicator.IsVisible = true; acIndicator.IsRunning = true; // 禁用按钮防止重复触发 btIndicatorOn.IsEnabled = false; try { // 执行地图相关UI操作 mapa.IsVisible = true; mapa.MoveToRegion(MapSpan.FromCenterAndRadius(new Location(41.21301, 1.73250), Distance.FromMiles(0.5))); string cadenaSituacion = " 41.21º N 1.73º E"; var pin = new Pin { Label = cadenaSituacion, Address = cadenaSituacion, Type = PinType.Place, Location = new Location(41.21301, 1.73250) }; mapa.Pins.Add(pin); // 异步调用数据加载方法 await ObtenerPrevisionAsync(); } catch (Exception ex) { // 这里可以添加异常处理逻辑,比如提示用户网络错误 // 例如:await DisplayAlert("错误", "加载数据失败:" + ex.Message, "确定"); } finally { // 无论成功失败,都隐藏Indicator并恢复按钮状态 acIndicator.IsVisible = false; acIndicator.IsRunning = false; btIndicatorOn.IsEnabled = true; } }
2. 将数据加载方法改为异步
替换过时的WebClient为更推荐的HttpClient,并将方法改为异步模式:
// 全局复用HttpClient实例,避免频繁创建导致Socket资源浪费 private readonly HttpClient _httpClient = new HttpClient(); public async Task ObtenerPrevisionAsync() { string url = string.Format("http://api.openweathermap.org/data/2.5/forecast?units=metric&lat={0}&lon={1}&lang=es&APPID={2}", viewModel.LatitudMapa, viewModel.LongitudMapa, OpenWeatherKey); // 异步获取JSON数据,不阻塞UI线程 var json = await _httpClient.GetStringAsync(url); var forecast = JsonConvert.DeserializeObject<weatherForecast>(json); // 清空旧数据,避免重复累积 DatosPrevision.Clear(); foreach (var item in forecast.list) { DatosPrevision.Add(new TreeViewNode(item.dt_txt) { Children = { new TreeViewNode(item.weather[0].description), new TreeViewNode($"Temperatura {String.Format("{0:N1}", item.main.temp)} ºC"), new TreeViewNode($"Dirección Viento {String.Format("{0:N1}", item.wind.deg)} º"), new TreeViewNode($"Velocidad Viento {String.Format("{0:N1}", ((item.wind.speed * 3600) / 1852))} Nudos"), new TreeViewNode($"Presión atmosférica sobre el suelo {item.main.grnd_level} hPa"), new TreeViewNode($"Presión atmosférica sobre el mar {item.main.sea_level} hPa"), new TreeViewNode($"Humedad {item.main.humidity}%"), } }); } // 更新TreeView数据源,await后默认回到主线程,无需额外切换 tvPrevision.ItemsSource = DatosPrevision; }
额外优化建议
- 全局复用
HttpClient:不要每次请求都创建新实例,避免Socket资源耗尽。 - 数据清空逻辑:每次加载新数据前清空
DatosPrevision,避免数据重复显示。 - 异常提示:在catch块中添加用户友好的错误提示,提升体验。
内容的提问来源于stack exchange,提问作者user1803086
相关产品推荐
相关产品推荐

