zoukankan      html  css  js  c++  java
  • Flutter 应用入门:路由管理

    路由(Route)在移动开发中通常指页面(Page),这跟web开发中单页应用的Route概念意义是相同的,Route在Android中通常指一个Activity,在iOS中指一个ViewController。所谓路由管理,就是管理页面之间如何跳转,通常也可被称为导航管理。Flutter中的路由管理和原生开发类似,无论是Android还是iOS,导航管理都会维护一个路由栈,路由入栈(push)操作对应打开一个新页面,路由出栈(pop)操作对应页面关闭操作,而路由管理主要是指如何来管理路由栈。

    // 路由管理
    
    
    // 导入包
    import 'package:flutter/material.dart';
    
    // 应用入口,启动Flutter应用,runApp它接受一个Widget参数
    void main() => runApp(MyApp());
    
    
    // MyApp类代表Flutter应用,它继承了 StatelessWidget类,这也就意味着应用本身也是一个widget
    class MyApp extends StatelessWidget {
      // widget的主要工作是提供一个build()方法来描述如何构建UI界面(通常是通过组合、拼装其它基础widget)
      @override
      Widget build(BuildContext context) {
        // MaterialApp是Material库中提供的Flutter APP框架,通过它可以设置应用的名称、主题、语言、首页以及路由列表等,它本身也是一个widget
        return MaterialApp(
          // 应用名称
          title: 'Flutter Demo',
          // 名为"home"的路由作为应用的home(首页)
          initialRoute: 'hmoe',
    
          // 应用主题
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
    
          // 注册路由表
          routes: {
            'new page':(context) => NewRoute(),
            // 将首页路由也注册为命名路由
            'home':(context) => MyHomePage(title: 'Flutter Demo Home Page'),
          },
    
          // 应用首页路由,本身也是一个widget
          home: MyHomePage(title: 'Flutter Demo Home Page'),
    
        );
      }
    }
    
    
    // Flutter应用的首页
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    // 有状态的组件(Stateful widget) 和无状态的组件(Stateless widget)有两点不同:
    // 1. Stateful widget可以拥有状态,这些状态在widget生命周期中是可以变的,而Stateless widget是不可变的。
    // 2. Stateful widget至少由两个类组成:
    // 一个StatefulWidget类;
    // 一个State类,StatefulWidget类本身是不变的,但是State类中持有的状态在widget生命周期中可能会发生变化。
    
    
    // 新路由,显示一句话
    class NewRoute extends StatelessWidget {
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('New route'),
          ),
          body: Center(
            child: Text('This is new route'),
          ),
        );
      }
    
    }
    
    
    // 路由传值。它接受一个提示文本参数,负责将传入它的文本显示在页面上,
    // 另外TipRoute中我们添加一个“返回”按钮,点击后在返回上一个路由的同时会带上一个返回参数。
    class TipRoute extends StatelessWidget {
      final String text;
      TipRoute({
        Key key,
        @required this.text,  // 接收一个text参数
      }) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('提示'),
          ),
          body: Padding(
            padding: EdgeInsets.all(18),
            child: Column(
              children: <Widget>[
                Text(text),
                RaisedButton(
                  onPressed: () => Navigator.pop(context, '我是返回值'),
                  child: Text('返回'),
                )
              ],
            ),
          ),
        );
      }
    }
    
    
    //// 打开TipRoute,已合并到_MyHomePageState了
    //class RouterTestRoute extends StatelessWidget {
    //  @override
    //  Widget build(BuildContext context) {
    //    return Center(
    //      child: RaisedButton(
    //        onPressed: () async {
    //          // 打开TipRoute,并等待返回结果
    //          var result = await Navigator.push(context, MaterialPageRoute(
    //            builder: (context) {
    //              return TipRoute(
    //                // 路由参数
    //                text: '我是提示***',
    //              );
    //            }
    //          ));
    //          // 输出TipRoute路由返回结果
    //          print('路由返回值:$result');
    //        },
    //        child: Text('打开提示页'),
    //      ),
    //    );
    //  }
    //}
    
    
    class _MyHomePageState extends State<MyHomePage> {
      // 组件的状态,记录按钮点击的总次数
      int _counter = 0;
    
      // 设置状态的自增函数
      /* 当按钮点击时,会调用此函数,该函数的作用是先自增_counter,然后调用setState 方法。
      setState方法的作用是通知Flutter框架,有状态发生了改变,Flutter框架收到通知后,会执行build方法来根据新的状态重新构建界面,
      Flutter 对此方法做了优化,使重新执行变的很快,所以你可以重新构建任何需要更新的东西,而无需分别去修改各个widget。
      */
      void _incrementCounter() {
        setState(() {
          _counter++;
        });
      }
    
      //
      @override
      Widget build(BuildContext context) {
        // Scaffold是Material库中提供的页面脚手架,它提供了默认的导航栏、标题和包含主屏幕widget树的body属性。
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          // Center组件,可以将其子组件树对齐到屏幕中心
          body: Center(
            // Column组件,可以将其所有子组件沿屏幕垂直方向依次排列
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(
                  'You have pushed the button this many times:',
                ),
                Text(
                  '$_counter',
                  style: Theme.of(context).textTheme.display1,
                ),
                // 添加一个新按钮
                FlatButton(
                  child: Text('Open new route!'),
                  textColor: Colors.blue,
                  onPressed: () {
    //                // 导航到新路由
    //                Navigator.push(context,
    //                    MaterialPageRoute(builder: (context) {
    //                      return NewRoute();
    //                    }));
    
                    // 通过路由名称来打开新路由
                    Navigator.pushNamed(context, 'new page');
                  },
                ),
                // 添加一个新按钮
                RaisedButton(
                  onPressed: () async {
                    // 打开TipRoute,并等待返回结果
                    var result = await Navigator.push(context, MaterialPageRoute(
                        builder: (context) {
                          return TipRoute(
                            // 路由参数
                            text: '我是提示信息哦!',
                          );
                        }
                    ));
                    // 输出TipRoute路由返回结果
                    print('路由返回值:$result');
                  },
                  child: Text('打开提示页'),
                ),
              ],
            ),
          ),
          // 页面右下角的带“+”的悬浮按钮,它的onPressed属性接受一个回调函数,代表它被点击后的处理器
          floatingActionButton: FloatingActionButton(
            onPressed: _incrementCounter,
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ),
        );
      }
    }
    
    
    

    总结

    介绍了Flutter中路由管理、传参的方式,然后又着重介绍了命名路由相关内容。在此需要说明一点,由于命名路由只是一种可选的路由管理方式,在实际开发中,可能心中会犹豫到底使用哪种路由管理方式。在此,根据经验,建议最好统一使用命名路由的管理方式,这将会带来如下好处:

    1. 语义化更明确。
    2. 代码更好维护;如果使用匿名路由,则必须在调用Navigator.push的地方创建新路由页,这样不仅需要import新路由页的dart文件,而且这样的代码将会非常分散。
    3. 可以通过onGenerateRoute做一些全局的路由跳转前置处理逻辑。
  • 相关阅读:
    ld: library not found for -lstdc++.6
    WebViewJavascriptBridge 进行js 与native通信。
    invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
    OC 与 js 界面JSBridge交互
    react-native init的时候出现问题:npm WARN React-native@0.35.0 requires a peer of react@~15.3.1 but none was
    react-无状态组件
    2018年末--积极拥抱h5.转载 大前端时代来临,我们何去何从?
    /Users/macbook/Library/Developer/Xcode/DerivedData/MapViewDemo: No such file or direc
    EXCEL中如何获得工作表(sheet)的名称
    DELPHI中Showmodal与Show的区别
  • 原文地址:https://www.cnblogs.com/parzulpan/p/12054468.html
Copyright © 2011-2022 走看看