14 . 跨组件共享数据
视图层级比较深的UI样式,直接通过属性传值会导致很多中间层增加冗余属性.
代码太多,见demo https://github.com/xfhy/FlutterBasic/tree/master/lib/data14.1 InheritedWidget
共享父Widget的属性14.2 Notification
从下往上的数据传递,在父Widget中监听来自子Widget的事件14.3 EventBus
EventBus 不依赖Widget树 这是事件总线,666 遵循发布订阅 模式14.4 对比
方式 数据流动方式 使用场景 属性传值 父到子 简单数据传递 InheritedWidget 父到子 跨层数据传递 Notification 子到父 状态通 EventBus 发布订阅 消息批量同步15 . 路由管理
Route是页面的抽象,主要负责创建对应的界面,接收参数,响应Navigator打开和关闭 Navigator则会维护一个路由栈管理Route,Route打开即入栈,Route关闭即出栈. 基本路由: 创建一个MaterialPageRoute实例,调用Navigator.push方法将新页面压到堆栈的顶部class FirstScreen extends StatelessWidget { @override Widget build(BuildContext context) { return RaisedButton( //打开页面 onPressed: ()=> Navigator.push(context, MaterialPageRoute(builder: (context) => SecondScreen())); ); } } class SecondPage extends StatelessWidget { @override Widget build(BuildContext context) { return RaisedButton( // 回退页面 onPressed: ()=> Navigator.pop(context) ); } }命名路由: 简化路由管理,命名路由.给页面起一个名字,然后通过名字打开
MaterialApp( ... //注册路由 routes:{ "second_page":(context)=>SecondPage(), }, ); //使用名字打开页面 Navigator.pushNamed(context,"second_page");错误路由处理,统一返回UnknownPage
MaterialApp( ... //注册路由 routes:{ "second_page":(context)=>SecondPage(), }, //错误路由处理,统一返回UnknownPage onUnknownRoute: (RouteSettings setting) => MaterialPageRoute(builder: (context) => UnknownPage()), ); //使用错误名字打开页面 Navigator.pushNamed(context,"unknown_page");页面参数: Flutter提供了路由参数的机制,可以在打开路由时传递相关参数,在目标页面通过RouteSettings来获取页面参数
//打开页面时传递字符串参数 Navigator.of(context).pushNamed("second_page", arguments: "Hey"); class SecondPage extends StatelessWidget { @override Widget build(BuildContext context) { //取出路由参数 String msg = ModalRoute.of(context).settings.arguments as String; return Text(msg); } }返回参数(类似startActivityForResult): 在push目标页面时,可以设置目标页面关闭时监听函数,以获取返回参数.而目标页面可以在关闭路由时传递相关参数.
class SecondPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: Column( children: <Widget>[ Text('Message from first screen: $msg'), RaisedButton( child: Text('back'), //页面关闭时传递参数 onPressed: ()=> Navigator.pop(context,"Hi") ) ] )); } } class _FirstPageState extends State<FirstPage> { String _msg=''; @override Widget build(BuildContext context) { return new Scaffold( body: Column(children: <Widget>[ RaisedButton( child: Text('命名路由(参数&回调)'), //打开页面,并监听页面关闭时传递的参数 onPressed: ()=> Navigator.pushNamed(context, "third_page",arguments: "Hey").then((msg)=>setState(()=>_msg=msg)), ), Text('Message from Second screen: $_msg'), ],), ); } }Navigator.push A->B->C->D,如何从 D页面 pop 到 B 呢? Navigator.popUntil(context,ModalRoute.withName('B'));
查看更多关于Flutter 入门笔记(Part 6) 跨组件共享数据,路由管理的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://www.haodehen.cn/did129225