123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- /*
- *
- * 路由封装
- * @params* [context] 当前页面上下文
- * @params* [targetPage] 跳转页面 非命名参数跳转时是 BuildContext 类型,路由命名参数跳转时是 字符串类型
- * @params [isPushNamed] 是否是命名参数跳转 默认false 非命名参数跳转; true 是
- * @params [arguments] 携带的参数 默认null
- * @params [opaque] 是否背景透明 默认false 不透明; true为透明
- * @params [isReplace] 是否替换当前页面 A-B 默认0 不替换; // 0 不替换 1 替换当前 2 替换当前及之前所有
- * @params [cb] // 返回上一级的回调函数 value 为传给上一级的参数
- *
- *
- *
- * 用法:
- * // 页面跳转
- GotoPage.pushPage(
- context: context,
- // targetPage: AppRoutes.mePage,
- targetPage: MePage(),
- animationType: AnimationType.rightToLeft,
- arguments: {"name": "gaolong"},
- cb: (value) => {print("---mePage返回的数据---$value------")},
- );
- *
- *
- *
- */
- import 'package:flutter/cupertino.dart';
- import 'package:flutter/material.dart';
- import 'device_utils.dart';
- //页面跳转动画的方式
- enum AnimationType { rightToLeft, leftToRight, bottomToTop, topToBottom }
- class GotoPage {
- // 非命名方式跳转 直接初始化页面对象
- static void _switchPageNotNamed({
- required BuildContext context,
- required dynamic targetPage,
- AnimationType? animationType = AnimationType.rightToLeft,
- int startMills = 300, // 动画过渡时间 300ms
- Object? arguments,
- num isReplace = 0, // 0 不替换 1 替换当前 2 替换当前及之前所有
- void Function(dynamic value)? cb,
- }) {
- PageRoute pageRoute;
- if (DeviceUtils.isAndroid) {
- // 安卓
- pageRoute = PageRouteBuilder(
- settings: RouteSettings(name: context.widget.key.toString(), arguments: arguments),
- transitionDuration: Duration(milliseconds: startMills),
- transitionsBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
- return SlideTransition(
- position: _createSlideTween(animationType).animate(animation),
- child: child,
- );
- },
- pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
- return targetPage;
- },
- );
- } else if (DeviceUtils.isIOS) {
- // 苹果
- pageRoute = CupertinoPageRoute(
- builder: (BuildContext context) {
- return targetPage;
- },
- settings: RouteSettings(name: context.widget.key.toString(), arguments: arguments),
- );
- } else {
- // 其他
- pageRoute = MaterialPageRoute(
- builder: (BuildContext context) {
- return targetPage;
- },
- settings: RouteSettings(name: context.widget.key.toString(), arguments: arguments),
- );
- }
- if (isReplace == 0) {
- // 不替换
- Navigator.of(context).push(pageRoute).then((value) {
- if (cb != null) {
- cb(value);
- }
- });
- } else if (isReplace == 1) {
- // 替换当前
- Navigator.of(context).pushReplacement(pageRoute).then((value) {
- if (cb != null) {
- cb(value);
- }
- });
- } else {
- // 替换当前及之前所有
- Navigator.of(context).pushAndRemoveUntil(pageRoute, (Route<dynamic>? route) => route == null).then((value) {
- if (cb != null) {
- cb(value);
- }
- });
- }
- }
- // 命名路由方式跳转
- static void _switchPageByNamed({
- required BuildContext context,
- required String targetPage,
- AnimationType? animationType = AnimationType.rightToLeft,
- int startMills = 300, // 动画过渡时间 300ms
- Object? arguments,
- num isReplace = 0, // 0 不替换 1 替换当前 2 替换当前及之前所有
- void Function(dynamic value)? cb, // 返回上一级的回调函数 value 为传给上一级的参数
- }) {
- if (isReplace == 0) {
- // 不替换
- Navigator.of(context).pushNamed(targetPage, arguments: arguments).then((value) => {
- if (cb != null) {cb(value)}
- });
- } else if (isReplace == 1) {
- // 替换当前
- Navigator.of(context).pushReplacementNamed(targetPage, arguments: arguments).then((value) => {
- if (cb != null) {cb(value)}
- });
- } else {
- // 替换当前及以前所有
- Navigator.of(context)
- .pushNamedAndRemoveUntil(targetPage, (Route route) => false, arguments: arguments)
- .then((value) => {
- if (cb != null) {cb(value)}
- });
- }
- }
- /// 1、普通跳转
- static void pushPage({
- required BuildContext context,
- required dynamic targetPage, // 非命名跳转时类型是 PageRoute 命令跳转时是 String
- AnimationType? animationType = AnimationType.rightToLeft,
- int startMills = 300, // 动画过渡时间 300ms
- Object? arguments, //携带参数
- num isReplace = 0, // 0 不替换 1 替换当前 2 替换当前及之前所有
- void Function(dynamic value)? cb, // 返回上一级的回调函数 value 为传给上一级的参数
- }) {
- bool _isPushNamed = targetPage is String ? true : false;
- if (!_isPushNamed) {
- //非路由命名方式跳转
- _switchPageNotNamed(
- context: context,
- targetPage: targetPage,
- animationType: animationType,
- startMills: startMills,
- arguments: arguments,
- isReplace: isReplace,
- cb: cb,
- );
- } else {
- // 路由命名跳转
- _switchPageByNamed(
- context: context,
- targetPage: targetPage,
- animationType: animationType,
- startMills: startMills,
- arguments: arguments,
- isReplace: isReplace,
- cb: cb,
- );
- }
- }
- /// 2、滑动过渡跳转
- static void pushPageBySlide({
- required BuildContext context,
- required dynamic targetPage, // 非命名跳转时类型是 PageRoute 命令跳转时是 String
- //默认'rightToLeft', 'leftToRight' 'bottomToTop' 'topToBottom'
- AnimationType? animationType = AnimationType.rightToLeft,
- bool? isPushNamed = true, // 是否是路由命名跳转 true 是 false 否
- bool opaque = true, // 背景透明方式 true: 不透明 false: 透明
- Object? arguments,
- int startMills = 300,
- num isReplace = 0, // 0 不替换 1 替换当前 2 替换当前及之前所有
- void Function(dynamic value)? cb, // 返回上一级的回调函数 value 为传给上一级的参数
- }) {
- bool _isPushNamed = targetPage is String ? true : false;
- if (_isPushNamed) {
- // 命名跳转 命名跳转时 没有动画效果 默认页面从 右向左切换
- _switchPageByNamed(
- context: context, targetPage: targetPage, arguments: arguments, isReplace: isReplace, cb: cb);
- } else {
- // 非命名跳转
- PageRoute pageRoute = PageRouteBuilder(
- settings: RouteSettings(name: context.widget.key.toString(), arguments: arguments),
- ///背景透明方式 true: 不透明 false: 透明
- opaque: opaque,
- pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
- return targetPage;
- },
- transitionDuration: Duration(milliseconds: startMills),
- ///动画
- transitionsBuilder:
- (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
- return SlideTransition(
- position: _createSlideTween(animationType).animate(animation),
- child: child,
- );
- },
- );
- if (isReplace == 0) {
- /// 不替换
- Navigator.of(context).push(pageRoute).then((value) {
- if (cb != null) {
- cb(value);
- }
- });
- } else if (isReplace == 1) {
- /// 替换当前
- Navigator.of(context).pushReplacement(pageRoute).then((value) {
- if (cb != null) {
- cb(value);
- }
- });
- } else {
- /// 替换当前及之前所有
- Navigator.of(context).pushAndRemoveUntil(pageRoute, (Route<dynamic>? route) => route == null).then((value) {
- if (cb != null) {
- cb(value);
- }
- });
- }
- }
- }
- static _createSlideTween(animationType) {
- Offset currentOffset;
- switch (animationType) {
- case AnimationType.rightToLeft:
- currentOffset = Offset(1, 0);
- break;
- case AnimationType.leftToRight:
- currentOffset = Offset(-1, 0);
- break;
- case AnimationType.bottomToTop:
- currentOffset = Offset(0, 1);
- break;
- case AnimationType.topToBottom:
- currentOffset = Offset(0, -1);
- break;
- default:
- currentOffset = Offset(1, 0);
- }
- return Tween<Offset>(
- begin: currentOffset,
- end: Offset.zero,
- );
- }
- /// 3、带渐变动画跳转
- static void pushPageByFade({
- required BuildContext context,
- required Widget targetPage,
- bool opaque = false, // 背景透明方式 true: 不透明 false: 透明
- dynamic arguments,
- int startMills = 300,
- num isReplace = 0, // 0 不替换 1 替换当前 2 替换当前及之前所有
- Function(dynamic value)? cb, // 返回上一级的回调函数 value 为传给上一级的参数
- }) {
- PageRoute pageRoute = PageRouteBuilder(
- settings: RouteSettings(name: context.widget.key.toString(), arguments: arguments ?? null),
- ///背景透明方式 true: 不透明 false: 透明
- opaque: opaque,
- pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
- return targetPage;
- },
- transitionDuration: Duration(milliseconds: startMills),
- ///动画
- transitionsBuilder:
- (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
- return FadeTransition(
- opacity: animation,
- child: child,
- );
- },
- );
- if (isReplace == 0) {
- /// 不替换
- Navigator.of(context).push(pageRoute).then((value) {
- if (cb != null) {
- cb(value);
- }
- });
- } else if (isReplace == 1) {
- /// 替换当前
- Navigator.of(context).pushReplacement(pageRoute).then((value) {
- if (cb != null) {
- cb(value);
- }
- });
- } else {
- /// 替换当前及之前所有
- Navigator.of(context).pushAndRemoveUntil(pageRoute, (Route<dynamic>? route) => route == null).then((value) {
- if (cb != null) {
- cb(value);
- }
- });
- }
- }
- static Route _createRoute(parentContext, Widget targetPage, int startMills, int reversMills, bool opaque, {dynamic arguments}) {
- return PageRouteBuilder<void>(
- settings: RouteSettings(name: parentContext?.widget?.key ?? '', arguments: arguments ?? null),
- opaque: opaque,
- // 背景透明方式 true: 不透明 false: 透明
- pageBuilder: (context, animation, secondaryAnimation) {
- return targetPage;
- },
- transitionDuration: Duration(milliseconds: startMills),
- reverseTransitionDuration: Duration(milliseconds: reversMills),
- transitionsBuilder: (context, animation, secondaryAnimation, child) {
- var rectAnimation = _createTween(parentContext).chain(CurveTween(curve: Curves.ease)).animate(animation);
- return Stack(
- children: [
- PositionedTransition(rect: rectAnimation, child: child),
- ],
- );
- },
- );
- }
- static Tween<RelativeRect> _createTween(BuildContext context) {
- var windowSize = MediaQuery.of(context).size;
- var box = context.findRenderObject() as RenderBox;
- var rect = box.localToGlobal(Offset.zero) & box.size;
- var relativeRect = RelativeRect.fromSize(rect, windowSize);
- return RelativeRectTween(
- begin: relativeRect,
- end: RelativeRect.fill,
- );
- }
- }
|