父组件跳转子组件

  • Navigator.push 是跳转到下一个页面,它要接受两个参数一个是context(上下文),另一个是要跳转的函数。
  • Navigator.pop 是返回到上一个页面,使用时传递一个context(上下文)参数,使用时要注意的是,你必须是有上级页面的,也就是说上级页面使用了Navigator.push ```dart import ‘package:flutter/material.dart’;

//传递的数据结构,也可以理解为对商品数据的抽象 class Product { final String title; //商品标题 final String description; //商品描述 Product(this.title, this.description); }

// void main() { // runApp(MaterialApp( // title: ‘数据传递案例’, // // List.generate生成的。并且这个生成的List原型就是我们刚开始定义的Product这个类(抽象数据) // home: ProductList( // products: List.generate(20, (i) => Product(‘商品 $i’, ‘这是一个商品详情,编号为:$i’)), // ))); // }

//分离后的 void main() => runApp(MyApp()); class MyApp extends StatelessWidget { const MyApp({Key key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: ‘数据传递案例’, // List.generate生成的。并且这个生成的List原型就是我们刚开始定义的Product这个类(抽象数据) home: ProductList( products: List.generate(20, (i) => Product(‘商品 $i’, ‘这是一个商品详情,编号为:$i’)), )); } }

class ProductList extends StatelessWidget { final List products; ProductList({Key key, @required this.products}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(‘商品列表’)), // 先接受了主方法传递过来的参数,接受后用ListView.builder方法,作了一个根据传递参数数据形成的动态列表。 body: ListView.builder( itemCount: products.length, itemBuilder: (context, index) { return ListTile( title: Text(products[index].title), onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => new ProductDetail(product: products[index]))); }); }, )); } }

class ProductDetail extends StatelessWidget { //接收父组件传来的参数 final Product product; ProductDetail({Key key, @required this.product}) : super(key: key);

@override Widget build(BuildContext context) { return new Scaffold( appBar: AppBar( title: Text(‘${product.title}’), ), body: Center( child: Text(‘${product.description}’), )); } }

  1. <a name="KMfF7"></a>
  2. ### 导航参数的传递和接收
  3. ```dart
  4. import 'package:flutter/material.dart';
  5. //传递的数据结构,也可以理解为对商品数据的抽象
  6. class Product {
  7. final String title; //商品标题
  8. final String description; //商品描述
  9. Product(this.title, this.description);
  10. }
  11. void main() {
  12. runApp(MaterialApp(
  13. title: '数据传递案例',
  14. home: ProductList(
  15. products: List.generate(20, (i) => Product('商品 $i', '这是一个商品详情,编号为:$i')),
  16. )));
  17. }
  18. class ProductList extends StatelessWidget {
  19. final List<Product> products;
  20. ProductList({Key key, @required this.products}) : super(key: key);
  21. @override
  22. Widget build(BuildContext context) {
  23. return Scaffold(
  24. appBar: AppBar(title: Text('商品列表')),
  25. body: ListView.builder(
  26. itemCount: products.length,
  27. itemBuilder: (context, index) {
  28. return ListTile(
  29. title: Text(products[index].title),
  30. onTap: () {
  31. Navigator.push(
  32. context,
  33. MaterialPageRoute(
  34. builder: (context) =>
  35. new ProductDetail(product: products[index])));
  36. });
  37. },
  38. ));
  39. }
  40. }
  41. class ProductDetail extends StatelessWidget {
  42. final Product product;
  43. ProductDetail({Key key, @required this.product}) : super(key: key);
  44. @override
  45. Widget build(BuildContext context) {
  46. return new Scaffold(
  47. appBar: AppBar(
  48. title: Text('${product.title}'),
  49. ),
  50. body: Center(
  51. child: Text('${product.description}'),
  52. ));
  53. }
  54. }

页面跳转并返回数据

  1. import 'package:flutter/material.dart';
  2. void main(){
  3. runApp(MaterialApp(
  4. title:'页面跳转返回数据',
  5. home:FirstPage()
  6. ));
  7. }
  8. class FirstPage extends StatelessWidget {
  9. @override
  10. Widget build(BuildContext context) {
  11. return Scaffold(
  12. appBar:AppBar(title:Text("找小姐姐要电话")),
  13. body:Center(
  14. child: RouteButton(),
  15. )
  16. );
  17. }
  18. }
  19. //跳转的Button
  20. class RouteButton extends StatelessWidget {
  21. @override
  22. Widget build(BuildContext context) {
  23. return RaisedButton(
  24. onPressed:(){
  25. _navigateToXiaoJieJie(context);
  26. },
  27. child: Text('去找小姐姐'),
  28. );
  29. }
  30. _navigateToXiaoJieJie(BuildContext context) async{ //async是启用异步方法
  31. final result = await Navigator.push(//等待
  32. context,
  33. MaterialPageRoute(builder: (context)=> XiaoJieJie())
  34. );
  35. Scaffold.of(context).showSnackBar(SnackBar(content:Text('$result')));
  36. }
  37. }
  38. class XiaoJieJie extends StatelessWidget {
  39. @override
  40. Widget build(BuildContext context) {
  41. return Scaffold(
  42. appBar:AppBar(
  43. title:Text('我是小姐姐')
  44. ),
  45. body:Center(
  46. child:Column(
  47. children: <Widget>[
  48. RaisedButton(
  49. child: Text('大长腿小姐姐'),
  50. onPressed: (){
  51. Navigator.pop(context,'大长腿:1511008888');
  52. },
  53. ) ,
  54. RaisedButton(
  55. child: Text('小蛮腰小姐姐'),
  56. onPressed: (){
  57. Navigator.pop(context,'小蛮腰:1511009999');
  58. },
  59. ) ,
  60. ],
  61. )
  62. ) ,
  63. );
  64. }
  65. }

SnackBar的使用

SnackBar是用户操作后,显示提示信息的一个控件,类似Tost

Scaffold.of(context).showSnackBar(SnackBar(content:Text('$result')));

返回数据的方式

返回数据其实是特别容易的,只要在返回时带第二个参数就可以了。

Navigator.pop(context,'xxxx');  //xxx就是返回的参数

Navigator.pop()的源代码

@optionalTypeArgs
static void pop<T extends Object?>(BuildContext context, [ T? result ]) {
  Navigator.of(context).pop<T>(result);
}

Flutter 返回上一页并刷新

用flutter路由跳转页面时,主要用到的就是 Navigator.push() 和 Navigator.pop() 两个方法。
但是存在一个问题:
当我从主页跳转到另一个页面,再返回到主页时,主页并不能主动刷新。怎么解决呢?
答案时,当返回到主页时,监听到返回事件,然后主动触发主页刷新。

class PageOne extends StatefulWidget {
  @override
  _PageOneState createState() => new _PageOneState();
}

class _PageOneState extends State<PageOne> {    // 第一个页面
  _getRequests()async{  
        print('这里进行操作');
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: RaisedButton(onPressed: ()=>
        Navigator.of(context).push(new MaterialPageRoute(builder: (_)=>PageTwo()),)
        .then((val)=>val?_getRequests():null), // 通过then进行监听回调参数
      ),
    ));
  }
}

class PageTwo extends StatelessWidget { // 第二个页面
  @override
  Widget build(BuildContext context) {
    //somewhere
    Navigator.pop(context,true); // 第二个就是需要传到参数
  }
}