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

Xamarin Forms Android端PopAsync自定义关闭动画实现求助

Android平台Xamarin.Forms PopAsync自定义动画实现方案

你遇到的问题根源在于OnDetachedFromWindow的触发时机:当这个方法执行时,页面已经从Window中移除,视图不再可见,所以动画根本不会被用户看到——这不是底层BUG,是方法的设计逻辑导致的。

要实现PopAsync时的自定义动画,必须在页面开始移除前启动动画,等动画完成后再执行Pop的最终逻辑,以下是两种可行的实现方案:

方案一:自定义NavigationPageRenderer(全局生效,推荐)

通过重写NavigationPage的Renderer,直接拦截Pop操作,在动画完成后再执行默认的Pop逻辑:

[assembly: ExportRenderer(typeof(NavigationPage), typeof(CustomNavigationRenderer))]
namespace YourAppNamespace.Droid.Renderers
{
    public class CustomNavigationRenderer : NavigationPageRenderer
    {
        public CustomNavigationRenderer(Context context) : base(context)
        {
        }

        public override async Task<bool> PopViewControllerAsync(bool animated)
        {
            // 判断是否启用自定义动画
            if (animated && Preferences.Get("ModelAnimationDetach", false))
            {
                var currentViewController = TopViewController;
                if (currentViewController?.View != null)
                {
                    // 创建自定义退出动画(可根据需求修改参数调整方向)
                    var displayMetrics = Context.Resources.DisplayMetrics;
                    var exitAnimation = new TranslateAnimation(0, displayMetrics.WidthPixels, 0, 0)
                    {
                        Duration = 2000,
                        FillAfter = true // 保持动画结束后的位置
                    };

                    // 动画完成后执行不带默认动画的Pop
                    exitAnimation.AnimationEnd += async (sender, e) =>
                    {
                        await base.PopViewControllerAsync(false);
                    };

                    // 启动动画
                    currentViewController.View.StartAnimation(exitAnimation);
                    return true; // 告知系统已处理Pop操作
                }
            }

            // 不满足条件时使用默认Pop逻辑
            return await base.PopViewControllerAsync(animated);
        }
    }
}

方案二:单个页面Renderer中处理(仅针对特定页面)

如果只需要给某个特定页面添加Pop动画,可以在该页面的Renderer中监听Disappearing事件,拦截默认导航后执行动画:

[assembly: ExportRenderer(typeof(YourTargetPage), typeof(YourPageRenderer))]
namespace YourAppNamespace.Droid.Renderers
{
    public class YourPageRenderer : PageRenderer
    {
        private bool _isAnimating;

        protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
        {
            base.OnElementChanged(e);

            if (e.NewElement != null)
            {
                e.NewElement.Disappearing += HandlePageDisappearing;
            }

            if (e.OldElement != null)
            {
                e.OldElement.Disappearing -= HandlePageDisappearing;
            }
        }

        private async void HandlePageDisappearing(object sender, EventArgs e)
        {
            if (_isAnimating || !Preferences.Get("ModelAnimationDetach", false))
                return;

            _isAnimating = true;
            var currentPage = sender as Page;
            var navigation = currentPage?.Navigation;

            if (navigation != null && navigation.NavigationStack.Count > 1 
                && navigation.NavigationStack.Last() == currentPage)
            {
                // 创建自定义动画
                var displayMetrics = Resources.DisplayMetrics;
                var exitAnimation = new TranslateAnimation(0, displayMetrics.HeightPixels, 0, 0)
                {
                    Duration = 2000,
                    FillAfter = true
                };

                exitAnimation.AnimationEnd += async (s, args) =>
                {
                    _isAnimating = false;
                    // 动画完成后执行无动画的Pop
                    await navigation.PopAsync(false);
                };

                // 启动动画
                View.StartAnimation(exitAnimation);

                // 阻止默认的Pop流程
                ((IElementController)currentPage).SendAppearing();
            }
        }
    }
}

注意事项

  • 动画完成后一定要调用不带动画的Pop方法(PopViewControllerAsync(false)或PopAsync(false)),避免默认动画和自定义动画冲突。
  • FillAfter = true属性可以确保动画结束后视图保持在最终位置,直到被移除。
  • 可根据需求调整动画的方向、时长等参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 21:05:16