ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Flutter Material Motion 预置动画指南:animations 包四大过渡模式与实战集成

Flutter Material Motion 预置动画指南:animations 包四大过渡模式与实战集成 Flutter Material Motion 预置动画指南animations 包四大过渡模式与实战集成【免费下载链接】packagesA collection of useful packages maintained by the Flutter team项目地址: https://gitcode.com/GitHub_Trending/pac/packages导读本文围绕 Flutter 官方维护的animations包展开系统讲解 Material motion 体系中的四大过渡模式Container transform容器变换、Shared axis共享轴、Fade through淡入淡出切换与 Fade淡入。你将学会通过OpenContainer、SharedAxisTransition、FadeThroughTransition、FadeScaleTransition等开箱即用的组件把经过设计验证的高质量转场动画直接嵌入自己的 Flutter 应用并了解PageTransitionSwitcher与showModal等底层基础设施的用法与实现原理。animations是 Flutter 团队维护的开源包当前仓库中版本为 3.0.0SDK 约束^3.12.0、Flutter3.44.0依赖material_ui它提供了一系列开箱即用pre-canned的高质量动画允许你用自定义内容替换动画载体后直接落入应用以取悦用户并提升交互质感。一、Material motion为何需要统一的转场模式Material motion 是一组帮助用户理解和导航应用的过渡模式。其设计哲学是转场动画不是装饰而是传达元素之间如何关联的信息。animations包把 Material motion 规范的四个核心模式固化为可直接复用的 Flutter 组件Container transform—— 用于包含容器的 UI 元素之间的转场在两个元素之间建立可见的联系Shared axis—— 用于具有空间或导航关系的 UI 元素之间的转场通过在 x、y 或 z 轴上施加共享变换强化元素间的关系Fade through—— 用于彼此没有强关联的 UI 元素之间的转场Fade—— 用于在屏幕边界内进入或退出的 UI 元素如对话框、菜单、Snackbar、FAB。选择哪种模式的核心依据是元素之间的语义关系强度从强关联容器变换到弱关联fade through再到无关联fade这构成了 Material motion 的完整过渡光谱。二、快速体验运行官方演示应用在真机或模拟器上查看上述动画的实际效果可进入包自带的示例工程cd packages/animations/example/ flutter run --release示例应用入口在 packages/animations/example/lib/main.dart主页以列表形式列出了四种过渡模式Container transform / Shared axis / Fade through / Fade并提供一个Slow animations开关通过timeDilation 20.0把动画放慢 20 倍方便逐帧观察动画曲线与元素运动细节。三、Container transformOpenContainerContainer transform模式专为包含容器的 UI 元素之间的转场设计例如卡片展开为详情页列表项展开为详情页FAB 展开为详情页搜索栏展开为全屏搜索。其核心组件是 OpenContainer一个点击后放大填满屏幕以揭示新内容的容器关闭状态下显示closedBuilder构建的 Widget点击后容器平滑放大至整个Navigator尺寸同时关闭态内容淡出、打开态内容淡入通过openBuilder提供的回调或 Android 返回键关闭时动画反向播放。3.1 最小示例OpenContainer( transitionDuration: const Duration(milliseconds: 500), transitionType: ContainerTransitionType.fadeThrough, openBuilder: (context, action) { return Scaffold( appBar: AppBar(title: const Text(Details Page)), body: const Center( child: Text( This page opened with Container Transform animation, style: TextStyle(fontSize: 18), textAlign: TextAlign.center, ), ), ); }, closedBuilder: (context, action) { return Container( width: 200, height: 120, alignment: Alignment.center, decoration: BoxDecoration( color: Colors.blue, borderRadius: BorderRadius.circular(16), ), child: const Text( Open Details, style: TextStyle(color: Colors.white, fontSize: 18), ), ); }, ),以上示例代码直接取自 open_container.dart 的文档注释展示了蓝色圆角卡片 → 全屏详情页的经典用法。3.2 完整参数说明参数类型默认值说明closedColorColorColors.white容器关闭时的背景色openColorColorColors.white容器打开时的背景色middleColorColor?主题canvasColor仅fadeThrough转场类型使用的中间过渡色closedElevationdouble1.0关闭时容器的海拔高度openElevationdouble4.0打开时容器的海拔高度closedShapeShapeBorder圆角 4.0 的RoundedRectangleBorder关闭时容器形状openShapeShapeBorder矩形RoundedRectangleBorder()打开时容器形状onClosedClosedCallbackT?null容器关闭pop时回调接收 pop 返回的数据未返回值时为nullclosedBuilderCloseContainerBuilder必填构建关闭状态内容可通过action回调打开容器openBuilderOpenContainerBuilderT必填构建打开状态内容可通过action回调关闭容器tappablebooltrue是否允许点击整个关闭态容器打开设为false时只能通过closedBuilder的action回调打开transitionDurationDuration300ms开/关转换动画时长transitionTypeContainerTransitionTypefade新旧内容的淡入淡出方式useRootNavigatorboolfalse路由推入最近的还是最远的NavigatorrouteSettingsRouteSettings?null提供给新路由的附加数据clipBehaviorClipClip.antiAlias关闭态内容的裁剪方式closedShadows/openShadowsListBoxShadow?null自定义阴影提供后对应的closedElevation/openElevation将被忽略3.3 实现原理从源码看OpenContainerState.openContainer()会构造一个私有的_OpenContainerRoute推入Navigator动画期间新旧内容同时存在于 Widget 树中因此两个 builder 返回的 Widget 不能使用相同的 GlobalKeyopen_container.dart。转场的核心是一组 TweenRectTween驱动容器从关闭位置/尺寸_rectTween.begin平滑放大到整个 Navigator 尺寸_rectTween.endShapeBorderTween驱动closedShape→openShape的形状变换ColorTween_getColorTween与透明度 Tween_getClosedOpacityTween/_getOpenOpacityTween根据ContainerTransitionType生成不同权重的TweenSequencefade模式关闭态内容保持不透明打开态内容在动画后 1/5 时间段内淡入同时背景色从closedColor渐变到openColorfadeThrough模式关闭态内容先淡出前 1/5 时间段背景色经由middleColor过渡打开态内容随后淡入。所有动画统一施加Curves.fastOutSlowIn曲线并通过_FlippableTweenSequence实现打开/关闭动画的精确反向回放中断转场如动画进行中再次点击由_transitionWasInterrupted检测并处理。四、Shared axis共享轴过渡Shared axis模式用于具有空间或导航关系的元素通过在 x、y、z 轴上共享同一变换方向强化上一屏与下一屏位于同一空间的感知引导页流程沿 x 轴过渡分步器stepper沿 y 轴过渡父子级导航沿 z 轴过渡。4.1 两种接入方式方式一作为全局页面转场。通过SharedAxisPageTransitionsBuilder挂到PageTransitionsTheme中替换所有MaterialPageRoute的默认转场示例取自 shared_axis_transition.dartMaterialApp( theme: ThemeData( pageTransitionsTheme: PageTransitionsTheme( builders: { TargetPlatform.android: SharedAxisPageTransitionsBuilder( transitionType: SharedAxisTransitionType.horizontal, ), TargetPlatform.iOS: SharedAxisPageTransitionsBuilder( transitionType: SharedAxisTransitionType.horizontal, ), }, ), ), // routes: ... );方式二作为局部内容切换。在PageTransitionSwitcher的transitionBuilder中直接使用SharedAxisTransition示例取自 shared_axis_transition.dartPageTransitionSwitcher( transitionBuilder: ( Widget child, Animationdouble primaryAnimation, Animationdouble secondaryAnimation, ) { return SharedAxisTransition( animation: primaryAnimation, secondaryAnimation: secondaryAnimation, transitionType: SharedAxisTransitionType.horizontal, child: child, ); }, child: Container( key: ValueKeyint(_selectedIndex), // 切换 key 才能触发过渡 color: _colors[_selectedIndex], child: const Center(child: FlutterLogo(size: 300)), ), ),4.2 轴类型与实现细节SharedAxisTransitionType枚举定义三种轴vertical—— 沿 y 轴垂直过渡适合注册/登录分步流程horizontal—— 沿 x 轴水平过渡适合向导、轮播类页面scaled—— 沿 z 轴缩放过渡适合父子级导航如点击进入详情。从 shared_axis_transition.dart 的实现可以看到其动画编排进入元素使用淡入_fadeInTransition在 0.31.0 区间内完成配合 30 像素位移x/y 轴或从 0.80 缩放到 1.00z 轴退出元素使用淡出_fadeOutTransition在 0.00.3 区间内完成配合反向位移或缩放到 1.10并以fillColor默认主题canvasColor作为过渡期间的背景色保证位移露出的区域颜色一致。通过DualTransitionBuilder分别驱动前进forwardBuilder与后退reverseBuilder方向的动画。五、Fade through淡入淡出切换Fade through模式用于彼此没有强关联的 UI 元素之间的切换典型场景点击底部导航栏的不同目的地点击刷新图标切换账号。它的特征与 Shared axis 一样是先出后进旧元素淡出然后新元素淡入并从 0.92 放大到 1.0。缩放仅施加在进入的元素上以强调新内容优先于旧内容。5.1 作为页面转场FadeThroughPageTransitionsBuilder同样挂载到PageTransitionsTheme示例取自 fade_through_transition.dartMaterialApp( theme: ThemeData( pageTransitionsTheme: PageTransitionsTheme( builders: { TargetPlatform.android: FadeThroughPageTransitionsBuilder(), TargetPlatform.iOS: FadeThroughPageTransitionsBuilder(), }, ), ), // routes: ... );5.2 与 PageTransitionSwitcher 组合在PageTransitionSwitcher.transitionBuilder中使用FadeThroughTransition即可为底部导航等场景的视图切换注入 fade through 动画示例取自 fade_through_transition.dartPageTransitionSwitcher( transitionBuilder: ( Widget child, Animationdouble primaryAnimation, Animationdouble secondaryAnimation, ) { return FadeThroughTransition( child: child, animation: primaryAnimation, secondaryAnimation: secondaryAnimation, ); }, child: Container( key: ValueKeyint(_selectedIndex), // 每次切换必须更换 key color: _colors[_selectedIndex], ), bottomNavigationBar: BottomNavigationBar( // items、currentIndex、onTap ... ), ),5.3 实现细节源码_ZoomedFadeIn/_FadeOutfade_through_transition.dart用两个TweenSequence精确控制时序淡入阶段在前 6/20 时间段内完全不透明透明度恒为 0、缩放恒为 0.92后 14/20 时间段内按Cubic(0.0, 0.0, 0.2, 1.0)曲线完成淡入与放大淡出阶段在前 6/20 时间段内按Cubic(0.4, 0.0, 1.0, 1.0)曲线淡出其余时间保持完全透明。两段动画错峰进行从而形成 fadethrough的视觉节奏。六、Fade淡入过渡FadeScaleTransition 与 showModalFade模式用于在屏幕边界内进入或退出的 UI 元素例如对话框菜单SnackbarFAB。实现上进入的元素快速淡入并从 80% 缩放到 100%退出的元素仅淡出——缩放同样只作用于进入元素。注意FadeScaleTransition不同于 Flutter 自带的FadeTransition后者只动画化子 Widget 的透明度。6.1 在普通场景使用FadeScaleTransition( animation: animation, // 通常来自 AnimationController child: child, )FadeScaleTransition通过DualTransitionBuilder组合两段动画fade_scale_transition.dart前进方向使用Interval(0.0, 0.3)淡入 0.80→1.00 缩放Easing.legacyDecelerate曲线后退方向使用 1.0→0.0 的透明度渐变。6.2 与 showModal 组合弹窗/菜单animations包还提供showModalAPI 与FadeScaleTransitionConfiguration将 fade 模式应用于模态弹窗示例取自 fade_scale_transition.dartshowModal( context: context, configuration: FadeScaleTransitionConfiguration(), builder: (BuildContext context) { return Center( child: SizedBox( width: 250, height: 250, child: const Material( child: Center(child: FlutterLogo(size: 250)), ), ), ); }, );FadeScaleTransitionConfiguration继承自ModalConfiguration可配置参数见 fade_scale_transition.dart参数默认值说明barrierColorColors.black54遮罩scrim颜色barrierDismissibletrue点击遮罩是否关闭弹窗transitionDuration150ms进入动画时长reverseTransitionDuration75ms退出动画时长barrierLabelDismiss遮罩的无障碍语义标签从 modal.dart 的实现可见showModal内部通过Navigator.push推入一个PopupRoute_ModalRoute其useRootNavigator默认为true——即模态默认推入根 Navigator。因此当应用存在多层Navigator时关闭弹窗应使用Navigator.of(context, rootNavigator: true).pop(result)而非普通的Navigator.pop。showModal返回FutureT?关闭时传入Navigator.pop的值即为该 Future 的解析结果。七、PageTransitionSwitcher模式化的 AnimatedSwitcherPageTransitionSwitcher是上述各过渡模式共享的基础设施page_transition_switcher.dart。它是AnimatedSwitcher的变体区别在于AnimatedSwitcher对进入/退出使用同一套动画而PageTransitionSwitcher允许像PageRoute一样分别指定进入转场primaryAnimation与退出转场secondaryAnimation。关键行为当child更换时transitionBuilder会被应用到新旧两个 child 上新 child 的primaryAnimation向前播放定义其出现旧 child 的secondaryAnimation向前播放定义其消失——相当于 push 一个新PageRoutereverse: true时行为反转相当于 pop 一个PageRoute切换必须更换 child 的Key若新旧 child 类型与 key 相同框架认为它们是同一个 Widget 而直接更新参数不会触发过渡。通常使用ValueKey区分如ValueKeyint(_selectedIndex)快速连续切换时多个旧 child 可以同时在树上淡出新 child 淡入layoutBuilder控制新旧 child 的布局默认defaultLayoutBuilder将所有条目放入居中对齐的Stack也可自定义如左上角对齐。八、库结构速览animations包的全部导出集中在 lib/animations.dart六个实现文件一一对应四种模式及两个基础设施文件对应模式 / 组件lib/src/open_container.dartContainer transformOpenContainer、ContainerTransitionTypelib/src/shared_axis_transition.dartShared axisSharedAxisTransition、SharedAxisPageTransitionsBuilder、SharedAxisTransitionTypelib/src/fade_through_transition.dartFade throughFadeThroughTransition、FadeThroughPageTransitionsBuilderlib/src/fade_scale_transition.dartFadeFadeScaleTransition、FadeScaleTransitionConfigurationlib/src/modal.dart模态弹窗基础设施showModal、ModalConfigurationlib/src/page_transition_switcher.dartPageTransitionSwitcher通用内容切换器对应的单元测试覆盖了各模式的核心行为test 目录fade_scale_transition_test.dart、fade_through_transition_test.dart、shared_axis_transition_test.dart、open_container_test.dart、modal_test.dart、page_transition_switcher_test.dart以及dual_transition_builder_test.dart可作为理解动画时序与中断处理行为的补充参考。九、集成到自己的应用在pubspec.yaml中声明依赖后即可使用dependencies: animations: ^3.0.0接入路径归纳如下页面级转场在ThemeData.pageTransitionsTheme中按平台配置SharedAxisPageTransitionsBuilder或FadeThroughPageTransitionsBuilder一键替换所有MaterialPageRoute的转场局部内容切换用PageTransitionSwitcherSharedAxisTransition/FadeThroughTransition为底部导航、Tab 内容区等注入专业转场容器展开用OpenContainer实现卡片/列表项/FAB/搜索栏到详情页的放大过渡弹窗与浮层用showModalFadeScaleTransitionConfiguration获得符合 Material 规范的淡入弹窗。结语animations包把 Material motion 规范中如何选择过渡模式的语义判断物化为四个可直接使用的组件和一套统一的切换基础设施。使用它时核心决策在于根据元素间的关系强度选择模式强关联用 Container transform空间/导航关联用 Shared axis弱关联用 Fade through屏幕内进出用 Fade。在此基础上通过各组件暴露的颜色、形状、海拔、时长与曲线参数即可将默认动画调整为符合应用视觉语言的自定义转场。【免费下载链接】packagesA collection of useful packages maintained by the Flutter team项目地址: https://gitcode.com/GitHub_Trending/pac/packages创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表