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

如何在Xamarin加载指示器中显示进度百分比并重置进度

Xamarin加载指示器进度不重置问题解决

问题描述

在Xamarin共享项目中实现了带百分比显示的加载指示器,但存在进度不重置的问题:返回主页面后再次进入目标页面,加载进度不会从1%开始,而是从上一次停止的位置继续累加。

问题原因

  1. 加载指示器中的progress字段是类级私有变量,未在每次加载前重置为0;
  2. 定时器在控件构造时启动后持续运行(TimerElapsed始终返回true),即使控件不可见,进度仍在后台累加;
  3. 控件实例可能被复用或持久化,导致上次的进度值被保留。

解决方案

1. 重构LoadingIndicator控件

修改控件代码,添加进度重置、定时器启停方法,避免定时器无效运行:

public partial class LoadingIndicator : ContentView
{
    private int progress = 0;
    private bool _timerRunning = false;

    public LoadingIndicator()
    {
        InitializeComponent();
        IsVisible = false;
    }

    /// <summary>
    /// 重置进度为0
    /// </summary>
    public void ResetProgress()
    {
        progress = 0;
        Txt.Text = "Progress: 0%";
    }

    /// <summary>
    /// 启动加载定时器
    /// </summary>
    public void StartLoading()
    {
        if (!_timerRunning)
        {
            _timerRunning = true;
            Device.StartTimer(TimeSpan.FromMilliseconds(300.0), TimerElapsed);
        }
        IsVisible = true;
    }

    /// <summary>
    /// 停止加载定时器
    /// </summary>
    public void StopLoading()
    {
        _timerRunning = false;
        IsVisible = false;
    }

    bool TimerElapsed()
    {
        Device.BeginInvokeOnMainThread(() =>
        {
            if (progress < 100)
            {
                progress++;
                Txt.Text = $"Progress: {progress}%";
            }
        });
        // 根据状态决定是否继续定时器
        return _timerRunning;
    }      
}

2. 修改调用逻辑

在触发加载的代码中,每次启动加载前重置进度并启动定时器,加载完成后停止定时器:

private async void ProductTypeButton_Clicked(object sender, EventArgs e)
{   
    _Model.IsProcessing = true;
    // 假设你的LoadingIndicator实例名为loadingIndicator
    loadingIndicator.ResetProgress();
    loadingIndicator.StartLoading();
           
    await _Model.GetProductStatus();
    await Task.Delay(300);
    try
    {                
        await Navigation.PushAsync(new ProductTypePage(_Model));              
    }
    finally
    {
        _Model.IsProcessing = false;
        loadingIndicator.StopLoading();
    }
}

3. 可选:MVVM模式优化(推荐)

如果项目采用MVVM架构,可以通过消息中心实现控件与ViewModel的解耦:

ViewModel中添加消息通知

private bool _isProcessing;
public bool IsProcessing
{
    get => _isProcessing;
    set
    {
        _isProcessing = value;
        OnPropertyChanged();
        if (_isProcessing)
        {
            MessagingCenter.Send(this, "StartLoading");
        }
        else
        {
            MessagingCenter.Send(this, "StopLoading");
        }
    }
}

LoadingIndicator中订阅消息

public LoadingIndicator()
{
    InitializeComponent();
    IsVisible = false;
    
    MessagingCenter.Subscribe<YourViewModelType>(this, "StartLoading", (sender) =>
    {
        ResetProgress();
        StartLoading();
    });
    
    MessagingCenter.Subscribe<YourViewModelType>(this, "StopLoading", (sender) =>
    {
        StopLoading();
    });
}

这样无需在页面代码后台直接操作控件,更符合MVVM设计原则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 00:35:17