好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Flutter 入门笔记(Part 6) 跨组件共享数据,路由管理

14 . 跨组件共享数据

视图层级比较深的UI样式,直接通过属性传值会导致很多中间层增加冗余属性.

代码太多,见demo https://github.com/xfhy/FlutterBasic/tree/master/lib/data

14.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) 跨组件共享数据,路由管理的详细内容...

  阅读:70次