You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shell页面跳转时,如何在目标页显示ActivityIndicator直至数据加载完成

问题分析

你的问题核心是UI线程被阻塞,导致Pending页面无法在数据加载过程中渲染ActivityIndicator,直到耗时操作完成后才一次性显示页面。具体原因有两点:

  1. Pending页的GetMyObjects方法中,耗时操作直接在UI线程执行,阻塞了页面渲染流程;
  2. 页面还未完成初始渲染就启动了同步耗时操作,ActivityIndicator根本没机会显示。
解决方案

1. 修正登录页LoginAsync逻辑

登录页的IsBusy仅控制自身加载状态,导航操作需异步执行,避免被Pending页的加载逻辑阻塞:

public async Task LoginAsync()
{
    try
    {
        IsBusy = true;
        // 先完成登录验证(如果有)
        await PerformLoginChecks();
        
        // 异步导航到Pending页,不等待页面加载完成
        await Shell.Current.GoToAsync("//Pending");
    }
    finally
    {
        IsBusy = false;
    }
}

2. 将Pending页耗时操作移到后台线程

修改ViewModel的GetMyObjects方法,把耗时逻辑放到后台线程执行,同时确保IsBusy状态正确通知UI:

public class PendingViewModel : INotifyPropertyChanged
{
    private bool _isBusy;
    public bool IsBusy
    {
        get => _isBusy;
        set
        {
            _isBusy = value;
            OnPropertyChanged(nameof(IsBusy));
        }
    }

    public async Task GetMyObjects()
    {
        try
        {
            IsBusy = true;
            // 把耗时操作放到后台线程,避免阻塞UI
            await Task.Run(() =>
            {
                // 模拟3秒耗时操作
                Thread.Sleep(3000);
                // 实际业务:获取数据
                // MyDataList = FetchFromApiOrDb();
            });
        }
        finally
        {
            IsBusy = false;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
    }
}

3. 异步执行Pending页的加载逻辑

修改页面后台的OnAppearing方法,异步调用加载方法,让页面先完成渲染再启动数据加载:

protected override async void OnAppearing()
{
    base.OnAppearing();
    // 异步加载,确保页面先渲染出ActivityIndicator
    await LoadData();
}

private async Task LoadData()
{
    await ViewModel.GetMyObjects();
}

4. 验证XAML绑定正确性

确保ActivityIndicator的绑定逻辑正确,能响应IsBusy状态变化:

<ActivityIndicator IsRunning="{Binding IsBusy}" 
                   IsVisible="{Binding IsBusy}"
                   HorizontalOptions="Center"
                   VerticalOptions="Center"/>
关键原理
  • UI线程仅负责页面渲染和用户交互,任何耗时操作必须放到后台线程,否则会导致UI冻结;
  • Shell的GoToAsync是异步操作,调用后会立即触发页面导航,但目标页面的同步耗时操作会阻塞渲染;
  • IsBusy的更新必须触发PropertyChanged事件,否则UI无法感知状态变化。

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 19:50:12