Flutter路由动画

(一)前言

在常规app开发中,肯定避免不了自定义路由动画,那么我们怎么给flutter定义路由动画呢。相信大家在谷歌搜索会出现很多定义路由动画的,但是按他们实现的动画,大部分是有一定缺陷的,

比如这种 路由动画 !!!!!!点我

(二)问题

按这种实现,正常进第一个页面没问题,但是如果再次使用MaterialPageRoute去下个页面,你会发现上个页面没出场动画

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class FadeRoute extends PageRoute {
  FadeRoute({
    required this.builder,
    this.transitionDuration = const Duration(milliseconds: 300),
    this.opaque = true,
    this.barrierDismissible = false,
    this.barrierColor,
    this.barrierLabel,
    this.maintainState = true,
  });

  final WidgetBuilder builder;

  
  final Duration transitionDuration;

  
  final bool opaque;

  
  final bool barrierDismissible;

  
  final Color? barrierColor;

  
  final String? barrierLabel;

  
  final bool maintainState;

  
  Widget buildPage(BuildContext context, Animation<double> animation,
          Animation<double> secondaryAnimation) =>
      builder(context);

  
  Widget buildTransitions(BuildContext context, Animation<double> animation,
      Animation<double> secondaryAnimation, Widget child) {
    return FadeTransition(
      opacity: animation,
      child: builder(context),
    );
  }
}

// 使用跳转
Navigator.push(
   context,
   FadePageRoute(
     builder: (context) => const RoutePage(),
   ),
 );

// 页面二次跳转
Navigator.push(
   context,
   MaterialPageRoute(
     builder: (context) => const DashLinePage(),
   ),
 );

结果动画
在这里插入图片描述

相关commit地址 !!!!!!点我

(三)问题处理

我们要处理这种情况,当然要修改当前路由动画,保证能不影响MaterialPageRoute再次使用时的逻辑。

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
// constants
import '../constants.dart';

class FadePageRoute extends PageRoute {
  FadePageRoute({
    required this.builder,
    this.transitionDuration = const Duration(milliseconds: 300),
    this.opaque = true,
    this.barrierDismissible = false,
    this.barrierColor,
    this.barrierLabel,
    this.maintainState = true,
  });

  final WidgetBuilder builder;

  
  final Duration transitionDuration;

  
  final bool opaque;

  
  final bool barrierDismissible;

  
  final Color? barrierColor;

  
  final String? barrierLabel;

  
  final bool maintainState;
  bool isPopGestureInProgress(PageRoute<dynamic> route) {
    return route.navigator!.userGestureInProgress;
  }

  
  bool canTransitionTo(TransitionRoute<dynamic> nextRoute) {
    // Don't perform outgoing animation if the next route is a fullscreen dialog.
    return (nextRoute is MaterialRouteTransitionMixin &&
            !nextRoute.fullscreenDialog) ||
        (nextRoute is CupertinoRouteTransitionMixin &&
            !nextRoute.fullscreenDialog);
  }

  
  Widget buildPage(BuildContext context, Animation<double> animation,
          Animation<double> secondaryAnimation) =>
      builder(context);
  
  Widget buildTransitions(BuildContext context, Animation<double> animation,
      Animation<double> secondaryAnimation, Widget child) {
    final bool linearTransition = isPopGestureInProgress(this);
    return SlideTransition(
      position: (linearTransition
              ? secondaryAnimation
              : CurvedAnimation(
                  parent: secondaryAnimation,
                  curve: Curves.linearToEaseOut,
                  reverseCurve: Curves.easeInToLinear,
                ))
          .drive(packetMiddleLeftTween), // 动画缩放值的变化
      textDirection: Directionality.of(context), // 动画执行的位置关系
      transformHitTests: false, // 点击事件是否落在动画后的控件上
      child: FadeTransition(
        opacity: animation,
        child: child,
      ),
    );
  }
}

相关的效果如下,另外多一个水波类型的录音动画。
在这里插入图片描述

相关commit地址 !!!!!!点我

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
想要在 Flutter 中为不同的路由(页面)设置不同的转场动画,可以通过自定义路由来实现。下面是一个简单的示例,演示如何创建一个自定义路由并为其设置不同的转场动画: 1. 创建一个自定义路由类 MyCustomRoute,继承自 MaterialPageRoute。 ```dart class MyCustomRoute extends MaterialPageRoute { MyCustomRoute({WidgetBuilder builder, RouteSettings settings}) : super(builder: builder, settings: settings); @override Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) { // 这里可以为不同的路由设置不同的转场动画 if (settings.name == '/page1') { return FadeTransition(opacity: animation, child: child); } else if (settings.name == '/page2') { return ScaleTransition(scale: animation, child: child); } else { // 默认的转场动画 return super.buildTransitions(context, animation, secondaryAnimation, child); } } } ``` 2. 在 MaterialApp 中使用自定义路由 ```dart class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'MyApp', initialRoute: '/', onGenerateRoute: (RouteSettings settings) { switch (settings.name) { case '/page1': return MyCustomRoute(builder: (_) => Page1(), settings: settings); case '/page2': return MyCustomRoute(builder: (_) => Page2(), settings: settings); default: return MyCustomRoute(builder: (_) => HomePage(), settings: settings); } }, ); } } ``` 在上面的示例中,我们为两个页面(/page1 和 /page2)设置了不同的转场动画,而对于其他页面则使用了默认的转场动画。 需要注意的是,这里的转场动画只是示例,你可以根据自己的需要来自定义转场动画。同时,建议在自定义路由类中重写 buildPage 方法,以便于在每次进入新页面时执行一些初始化操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值