如何禁用Xamarin.Forms 4.0+ iOS端Shell导航的所有动画?
如何禁用Xamarin.Forms Shell侧边菜单(Flyout)切换页面的动画?
我之前也遇到过一模一样的问题——手动调用Shell.GoToAsync(..., animate: false)能关掉动画,但侧边菜单触发的FlyoutItem跳转是框架自动处理的,iOS会出现烦人的透明度混合动画,Android则是直接切换但带着明显闪烁,确实头疼。下面分平台给你具体的解决方案:
iOS端:彻底禁用Flyout切换的透明度动画
我们可以通过自定义ShellRenderer来拦截iOS的导航动画逻辑,强制关闭所有Shell导航的动画:
在你的iOS项目里创建一个自定义渲染器类:
[assembly: ExportRenderer(typeof(AppShell), typeof(CustomShellRenderer))] namespace YourAppName.iOS.Renderers { public class CustomShellRenderer : ShellRenderer { protected override IShellSectionRenderer CreateShellSectionRenderer(ShellSection shellSection) { return new CustomShellSectionRenderer(this); } } public class CustomShellSectionRenderer : ShellSectionRenderer { public CustomShellSectionRenderer(IShellContext context) : base(context) { } // 强制所有页面出现时不使用动画 public override void ViewWillAppear(bool animated) { base.ViewWillAppear(false); } // 或者拦截导航动作,强制关闭动画 protected override Task NavigateFromAsync(ShellSection fromSection, bool animate) { return base.NavigateFromAsync(fromSection, false); } } }
替换掉上面的YourAppName和AppShell为你项目里的实际名称,这样iOS端的Flyout切换动画就完全消失了。
Android端:解决页面切换时的闪烁问题
Android端的闪烁是因为默认的页面过渡逻辑导致的,同样用自定义ShellRenderer来处理:
在Android项目里创建对应的渲染器:
[assembly: ExportRenderer(typeof(AppShell), typeof(CustomShellRenderer))] namespace YourAppName.Droid.Renderers { public class CustomShellRenderer : ShellRenderer { public CustomShellRenderer(Context context) : base(context) { } protected override IShellNavHostController CreateNavHostController(Shell shell) { var navController = base.CreateNavHostController(shell); // 拦截导航参数,强制设置animate为false navController.Navigator.ExtrasProvider = (viewModel, extras) => { if (extras is ShellNavigationQueryArgs shellArgs) { shellArgs.Animate = false; } return extras; }; return navController; } } }
另外,你还可以在Android的styles.xml主题里添加一行配置,进一步消除系统层面的动画:
<style name="MainTheme" parent="MainTheme.Base"> <!-- 其他配置 --> <item name="android:windowAnimationStyle">@null</item> </style>
这样Android端的页面切换就会变得平滑无闪烁了。
补充说明
正如用户Depechie提到的,理论上Shell的Flyout切换默认应该是animate=false,但iOS端确实存在这个默认行为不一致的小问题,上面的自定义渲染器方法刚好能覆盖框架的默认逻辑,完美解决问题。
内容的提问来源于stack exchange,提问作者this.myself
相关产品推荐
相关产品推荐

