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

.NET MAUI:停止动画后如何阻止OnProgressComplete完成事件触发

.NET MAUI动画停止后避免触发完成事件的正确方式

问题场景

你在.NET MAUI中通过Animation类修改AbsoluteLayout内元素尺寸,动画代码如下:

_animationProgress = new Animation(v => AbsoluteContainer.SetLayoutBounds(RectangleProgress, new Rect() { Height = 1, Width = v}), 0, 1);
_animationProgress.Commit(
    this,
    "TrackListSideBarAnimation",
    16,
    DurationMs,
    Easing.Linear,
    OnProgressComplete);

当用户手动停止动画时,你不希望触发OnProgressComplete事件,但调用自定义的Stop方法后事件仍会执行:

public void Stop()
{
    if (_animationProgression != null)
    {
        _animationProgress.Finished = null;
        _animationProgress.Pause();
        _animationProgress.RemoveFromParent();
        _animationProgress.Dispose();
        _animationProgress = null;
    }
}

原因说明

直接操作Animation实例的Pause、Dispose等方法无法彻底终止MAUI动画系统中已提交的动画。因为调用Commit后,动画实例会被MAUI的内部动画管理器托管,你修改的本地实例引用和系统中托管的实例可能存在分离,导致Finished事件回调依然被系统触发。

正确解决方案

使用View的AbortAnimation方法,通过动画名称直接终止MAUI动画系统中的对应动画,这样能彻底移除动画的所有回调,不会触发完成事件:

public void Stop()
{
    // 通过动画名称终止系统中的动画
    this.AbortAnimation("TrackListSideBarAnimation");
    
    // 清理本地引用
    if (_animationProgress != null)
    {
        _animationProgress.Dispose();
        _animationProgress = null;
    }
}

额外优化方案

如果担心极端场景下事件仍被触发(比如动画在Abort前已进入完成回调队列),可以添加一个状态标记来控制OnProgressComplete的执行逻辑:

private bool _isAnimationStopped = false;

public void Stop()
{
    _isAnimationStopped = true;
    this.AbortAnimation("TrackListSideBarAnimation");
    
    if (_animationProgress != null)
    {
        _animationProgress.Dispose();
        _animationProgress = null;
    }
}

private void OnProgressComplete(double v, bool canceled)
{
    // 已停止则跳过逻辑
    if (_isAnimationStopped)
    {
        _isAnimationStopped = false; // 重置状态,方便下次动画使用
        return;
    }
    
    // 原本的完成逻辑
    // ...
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 02:22:39