.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
相关产品推荐
相关产品推荐

