Flutter(二十六)——自定义路由

简介: Flutter(二十六)——自定义路由

PageRouteBuilder


前面我们介绍的所有路由都是MaterialPageRoute。但这并不能满足项目中的实际需求,有时候我们也需要修改路由默认的转场效果,这个时候就需要自定义路由,要用到另一个类,它就是PageRouteBuilder,首先我们来看看它的源码:

PageRouteBuilder({
    RouteSettings settings,
    @required this.pageBuilder,
    this.transitionsBuilder = _defaultTransitionsBuilder,
    this.transitionDuration = const Duration(milliseconds: 300),
    this.opaque = true,
    this.barrierDismissible = false,
    this.barrierColor,
    this.barrierLabel,
    this.maintainState = true,
    bool fullscreenDialog = false,
  }) : assert(pageBuilder != null),
       assert(transitionsBuilder != null),
       assert(opaque != null),
       assert(barrierDismissible != null),
       assert(maintainState != null),
       assert(fullscreenDialog != null),
       super(settings: settings, fullscreenDialog: fullscreenDialog);


属性讲解


我们来看一下PageRouteBuilder源码中几个重要的属性,如下图所示:

属性 取值
Opaque 是否遮挡整个屏幕
transitionsBuilder 用于自定义的转场效果
pageBuilder 用来创建所要跳转到的页面
transitionDuration 转场动画的持续时间


自定义路由转场效果


介绍完几个重要的属性,我们就直接来实战把,这里我们将通过一个自定义的Widget和PageRouteBuild,实现一个简单的Hero效果的路由转场,首先,我们定义一个方法,用于路由的切换,代码如下:

_customToButton(Widget page){
    Navigator.of(context).push(
      PageRouteBuilder<Null>(
        pageBuilder: (BuildContext context,Animation<double> anim1,Animation<double> anim2){
          return AnimatedBuilder(
            animation: anim1,
            builder: (BuildContext context,Widget child){
              return Opacity(
                opacity: anim1.value,
                child: page,
              );
            },
          );
        },
        transitionDuration: Duration(milliseconds: 600)
      ),
    );
  }


属性上面对应的表格都有,其他属性一眼就能看出来,这里就不在赘述,接着我们需要定义一个通过Hero动画变化的一个CustomLogo自定义图标,代码如下:

class CustomLogo extends StatelessWidget{
  final double size;
  CustomLogo({this.size=200.0});
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.blueAccent,
      width: size,
      height: size,
      child: Center(
        child: FlutterLogo(
          size: size,
        ),
      ),
    );
  }
}


然后,我们需要完善主界面的元素,需要Button点击实现路由的跳转,代码如下:

class _MyHomePageState extends State<MyHomePage> {
  _customToButton(Widget page){
    ....代码在上面
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            RaisedButton(
              padding: EdgeInsets.all(10),
              onPressed: (){
                _customToButton(Page2());
              },
              child: Text(
                '跳转自定义路由',
                textAlign: TextAlign.center,
                style: TextStyle(fontSize: 15),
              ),
            ),
            Hero(
              tag: 'hero1',
              child: ClipOval(
                child: CustomLogo(size: 60,),
              ),
            ),
            Hero(
              tag: 'hero2',
              child: Material(
                color: Colors.transparent,
                child: Text(
                  '动画',
                  style: TextStyle(fontSize: 15,color: Colors.red),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}


前面我们讲过,如果需要实现Hero动画,必须定义源和目标,所以我们跳转的界面也要有一个tag是hero1,代码如下:

class Page2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: EdgeInsets.all(30.0),
        child: Stack(
          children: <Widget>[
            Align(
              alignment: Alignment.center,
              child: Hero(
                tag: "hero1",
                child: Container(
                  height: 250.0,
                  width: 250.0,
                  child: CustomLogo(),
                ),
              ),
            ),
            OutlineButton(
              onPressed: () => Navigator.of(context).pop(),
              child: Icon(Icons.close),
            )
          ],
        ),
      ),
    );
  }
}

上面的代码都是前面讲解过的基本元素,除了第一段代码提取出来的方法_customToButton,其他的都使用过,不懂的可以前往前面的章节了解。最后我们运行一下,就实现如下效果:

相关文章
|
2天前
|
API 网络架构
一文带你了解 Flutter 路由
一文带你了解 Flutter 路由
|
1月前
|
UED 开发者 容器
Flutter&鸿蒙next 的 Sliver 实现自定义滚动效果
Flutter 提供了强大的滚动组件,如 ListView 和 GridView,但当需要更复杂的滚动效果时,Sliver 组件是一个强大的工具。本文介绍了如何使用 Sliver 实现自定义滚动效果,包括 SliverAppBar、SliverList 等常用组件的使用方法,以及通过 CustomScrollView 组合多个 Sliver 组件实现复杂布局的示例。通过具体代码示例,展示了如何实现带有可伸缩 AppBar 和可滚动列表的页面。
110 1
|
1月前
Flutter 自定义组件继承与调用的高级使用方式
本文深入探讨了 Flutter 中自定义组件的高级使用方式,包括创建基本自定义组件、继承现有组件、使用 Mixins 和组合模式等。通过这些方法,您可以构建灵活、可重用且易于维护的 UI 组件,从而提升开发效率和代码质量。
131 1
|
1月前
|
Go 网络架构 开发者
Flutter &鸿蒙next中的路由使用详解【基础使用】
本文介绍了 Flutter 路由系统的使用方法,包括基本路由、命名路由、参数传递、返回参数和动态路由。通过 `Navigator` 类实现页面跳转,支持简单和复杂参数的传递,并可通过 `onGenerateRoute` 实现更灵活的动态路由管理。示例代码展示了如何在实际项目中应用这些技术,帮助开发者构建清晰、易于维护的导航结构。
87 1
|
1月前
|
前端开发 开发者
深入探索 Flutter 鸿蒙版的画笔使用与高级自定义动画
本文深入探讨了 Flutter 中的绘图功能,重点介绍了 CustomPainter 和 Canvas 的使用方法。通过示例代码,详细讲解了如何绘制自定义图形、设置 Paint 对象的属性以及实现高级自定义动画。内容涵盖基本绘图、动画基础、渐变动画和路径动画,帮助读者掌握 Flutter 绘图与动画的核心技巧。
80 1
|
1月前
|
Dart UED 开发者
Flutter&鸿蒙next中的按钮封装:自定义样式与交互
在Flutter应用开发中,按钮是用户界面的重要组成部分。Flutter提供了多种内置按钮组件,但有时这些样式无法满足特定设计需求。因此,封装一个自定义按钮组件变得尤为重要。自定义按钮组件可以确保应用中所有按钮的一致性、可维护性和可扩展性,同时提供更高的灵活性,支持自定义颜色、形状和点击事件。本文介绍了如何创建一个名为CustomButton的自定义按钮组件,并详细说明了其样式、形状、颜色和点击事件的处理方法。
86 1
|
1月前
|
Dart 搜索推荐 API
Flutter & 鸿蒙next版本:自定义对话框与表单验证的动态反馈与错误处理
在现代移动应用开发中,用户体验至关重要。本文探讨了如何在 Flutter 与鸿蒙操作系统(HarmonyOS)中创建自定义对话框,并结合表单验证实现动态反馈与错误处理,提升用户体验。通过自定义对话框和表单验证,开发者可以提供更加丰富和友好的交互体验,同时利用鸿蒙next版本拓展应用的受众范围。
84 1
|
2月前
|
UED 开发者
flutter:获取对象&路由管理 (四)
本文介绍了Flutter中如何通过Context获取状态对象、使用GlobalKey获取状态对象、基本的路由管理、路由传值、命名路由、返回根路由以及点击图标跳转的方法。示例代码展示了如何在应用中实现这些功能,包括页面跳转、传递参数和返回上一页等操作。
|
3月前
|
前端开发 搜索推荐
Flutter中自定义气泡框效果的实现
Flutter中自定义气泡框效果的实现
114 3
|
4月前
|
开发者 监控 开发工具
如何将JSF应用送上云端?揭秘在Google Cloud Platform上部署JSF应用的神秘步骤
【8月更文挑战第31天】本文详细介绍如何在Google Cloud Platform (GCP) 上部署JavaServer Faces (JSF) 应用。首先,确保已准备好JSF应用并通过Maven构建WAR包。接着,使用Google Cloud SDK登录并配置GCP环境。然后,创建`app.yaml`文件以配置Google App Engine,并使用`gcloud app deploy`命令完成部署。最后,通过`gcloud app browse`访问应用,并利用GCP的监控和日志服务进行管理和故障排查。整个过程简单高效,帮助开发者轻松部署和管理JSF应用。
64 0