使用MaterialPageRoute
也就是页面路由,可以实现不同Widget之间的跳转
页面只是一个全屏的Widget
先写好另一个页面的Widget
1 | class DetailPage extends StatefulWidget { |
简单的页面跳转
1 | Navigator.push(context, MaterialPageRoute(builder: (_){ |
既然是push,那么就是个栈模型了,跳转到另一个页面相当于入栈
如果要返回到上一级页面可以这样做,pop相当于是出栈
1 | Navigator.pop(context); |
命名路由
可以在MaterialApp当中传入routes参数,该参数是一个Map对象
key是路由名称,value是返回组件对象的函数
1 | class MyApp extends StatelessWidget { |
通常的习惯当然是把routes这部分封装在一个单独的模块当中引入使用
命名路由的跳转
1 | Navigator.pushNamed(context, '/detail'); |
这种方式不需要反复构建和销毁组件对象,相对来讲是更好的一种方式
路由传参
基本的Navigator.push的方式是构建组件,当然可以给组件的构造方法传入参数,比如上面传入的title
这个就不需要特别的传参方式了,如果使用命名路由跳转
可以传入第三个可选参数arguments
1 | Navigator.pushNamed(context, '/detail', arguments: {'id': 1001}); |
arguments可以是任意的Object
接收参数方式
1 | ModalRoute.of(context).settings.arguments |
当然不论传入的是什么,此时获取到的还是Object类型,需要使用as Map<String, int>
(取决于传入的类型而执行的类型推导)
进行强制类型转换
组件之间的共享状态
除了组件之间的传参,以及路由的传参之外,组件之间通常需要有一些状态需要共享
比如一个常见的需求是用户登录之后,在每个页面上都能看到当前登录的用户是什么名字
需要使用到的是provider
这个第三方模块
先定义Model
1 | // user.dart |
还有
1 | // user.g.dart |
为了能够在启动时读取上次运行的缓存
需要使用shared_preferences
这个第三方模块
定义全局对象
1 | // global.dart |
profile当中可以持有User对象
这种情况下就需要在应用启动时就初始化Global对象
1 | void main() => Global.init().then((e) => runApp(MyApp())); |
自定义Notifier
1 | class ProfileChangeNotifier extends ChangeNotifier { |
根组件需要使用InheritedProvider进行包装
1 | class MyApp extends StatelessWidget { |
共享状态的更新,比如在登录时,需要把当前用户的信息写入profile,并且传播到各个组件当中
这里简单写入一个username作为例子
1 | Provider.of<UserModel>(context).user = User.fromJson({'username': _usernameController.text}); |