• Flutter参数的传递和接收


    上次只写了方法和参数,这次写了完整的示例,页面间参数的传递和接收的示例。

    1、参数传递

    用在程序上解释就是比如你进入一个商品选择列表,当你想选择一个商品的具体信息的时候,你就要传递商品编号,详细页面接受到编号后,显示出不同的内容。

    声明数据结构类

    Dart中可以使用类来抽象一个数据,比如我们模仿一个商品信息,有商品标题和商品描述。我们定义了一个Product类,里边有两个字符型变量,title和description。

    • title:是商品标题。
    • description: 商品详情描述
    class Product{
      final String title;  //商品标题
      final String description;  //商品描述
      Product(this.title,this.description);
    }

    构建一个商品列表

    作一个商品的列表,这里我们采用动态的构造方法,在主方法里传递一个商品列表(List)到自定义的Widget中。

    先来看看主方法的编写代码:

    import 'package:flutter/material.dart';
    
    void main(){
      runApp(MaterialApp(
        title:'数据传递案例',
        home:ProductList(
          products:List.generate(
            20, 
            (i)=>Product('商品 $i','这是一个商品详情,编号为:$i')
          ),
        )
      ));
    }

    上面的代码是主路口文件,主要是在home属性中,我们使用了ProductList,这个自定义组件,而且时候会报错,因为我们缺少这个组件。这个组件我们传递了一个products参数,也就是商品的列表数据,这个数据是我们用List.generate生成的。并且这个生成的List原型就是我们刚开始定义的Product这个类(抽象数据)。

    ProductList自定义组件的代码:

    class ProductList extends StatelessWidget{
      final List<Product> products;
      ProductList({Key key,@required this.products}):super(key:key);
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title:Text('商品列表')),
          body:ListView.builder(
            itemCount:products.length,
            itemBuilder: (context,index){
              return ListTile(
                title:Text(products[index].title),
                onTap:(){
    
                }
              );
            },
          )
        );
      }
    }

    先接受了主方法传递过来的参数,接受后用ListView.builder方法,作了一个根据传递参数数据形成的动态列表。

    参数的传递

    还是使用Navigator组件,然后使用路由MaterialPageRoute传递参数,具体代码如下。

    Navigator.push(
      context, 
      MaterialPageRoute(
        builder:(context)=>new ProductDetail(product:products[index])
      )
    );

    子页面接受参数并显示

    现在需要声明ProductDetail这个类(组件),先要作的就是接受参数,具体代码如下。

    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}'),)
        );
      }
    }

    接受了参数,并把数据显示在了页面中。

    完成代码如下:

    import 'package:flutter/material.dart';
    
    //传递的数据结构,也可以理解为对商品数据的抽象
    class Product{
      final String title;  //商品标题
      final String description;  //商品描述
      Product(this.title,this.description);
    }
    
    void main(){
      runApp(MaterialApp(
        title:'数据传递案例',
        home:ProductList(
          products:List.generate(
            20, 
            (i)=>Product('商品 $i','这是一个商品详情,编号为:$i')
          ),
        )
      ));
    }
    
    class ProductList extends StatelessWidget{
      final List<Product> products;
      ProductList({Key key,@required this.products}):super(key:key);
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title:Text('商品列表')),
          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}'),)
        );
      }
    }

    也可以如下方式,效果是一样的:

    import 'package:flutter/material.dart';
    
    class Product{//抽象类
      final String title;  //商品标题
      final String description;  //商品描述
      Product(this.title,this.description);
    }
    
    class ProductList extends StatefulWidget{
      //接收参数
      final List<Product> products;
      ProductList({Key key,@required this.products}):super(key:key);
    
      @override
      State<StatefulWidget> createState() {
        return new ProductListState();
      }
    }
    
    
    class ProductListState extends State<ProductList>{
      
      final products = List.generate(
          20, (i)=>Product('商品 $i','这是一个商品详情,编号为:$i')
      );
      
      @override
      Widget build(BuildContext context) {
        return Scaffold(  //可以直接用return Scaffold()
            appBar: AppBar(title:Text('列表页面')),
            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}'),)
        );
      }
    }

    2、页面跳转并返回数据

    当我们返回页面时返回结果到上一个页面(也就是父页面)。这样的场景经常用于,我们去子页面选择了一项选项,然后把选择的结果返回给父级页面。

    异步请求和等待

    Dart中的异步请求和等待和ES6中的方法很像,直接使用async...await就可以实现。比如下面作了一个找商品的方法,然后进行跳转,注意这时候是异步的。等待结果回来之后,我们再显示出来内容。具体代码如下:

    _navigateToXiaoJieJie(BuildContext context) async{ //async是启用异步方法
        final result = await Navigator.push( //等待
          context,
          MaterialPageRoute(builder: (context)=>ItemDetail())
        );
        //SnackBar是用户操作后,显示提示信息的一个控件,类似Tost,会自动隐藏。SnackBar是以Scaffold的showSnackBar方法来进行显示的
        Scaffold.of(context).showSnackBar(SnackBar(content:Text('$result')));
    
        setState(() {
          showText= '$result';
        });
    
      }

    SnackBar的使用

    SnackBar是用户操作后,显示提示信息的一个控件,类似Tost,会自动隐藏。SnackBar是以ScaffoldshowSnackBar方法来进行显示的。

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

    返回数据的方式

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

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

    我还加了一个showText,方便更好的看清楚效果。代码如下:

    import 'package:flutter/material.dart';
    
    class ItemPage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text('要编号'),),
          body: Center(
            child: RouteButton(),
          ),
        );
      }
    }
    
    class RouteButton extends StatefulWidget {
      _RouteButtonState createState() => _RouteButtonState();
    }
    
    class _RouteButtonState extends State<RouteButton> {
      String showText = '';
    
      @override
      Widget build(BuildContext context) {
        return Container(
           child: Column(
             children: <Widget>[
               RaisedButton(
                 onPressed: (){
                   _navigateToXiaoJieJie(context);
                 },
                 child: Text('要编号'),
               ),
               Text(showText),
             ],
           ),
        );
      }
    
      _navigateToXiaoJieJie(BuildContext context) async{ //async是启用异步方法
        final result = await Navigator.push( //等待
          context,
          MaterialPageRoute(builder: (context)=>ItemDeetail())
        );
        //SnackBar是用户操作后,显示提示信息的一个控件,类似Tost,会自动隐藏。SnackBar是以Scaffold的showSnackBar方法来进行显示的
        Scaffold.of(context).showSnackBar(SnackBar(content:Text('$result')));
    
        setState(() {
          showText= '$result';
        });
    
      }
    
    }
    
    
    class ItemDeetail extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text('商品编号')),
          body: Center(
            child: Column(
              children: <Widget>[
                RaisedButton(
                  child: Text('1号商品'),
                  onPressed: (){
                    Navigator.pop(context,'1号编号:123'); //第2个参数是返回的参数
                  },
                ),
                RaisedButton(
                  child: Text('2号商品'),
                  onPressed: (){
                    Navigator.pop(context,'2号编号:456'); //返回的参数
                  },
                ),
              ],
            ),
          ),
        );
      }
    }
  • 相关阅读:
    开源 免费 java CMS FreeCMS功能说明单位管理
    用Spring让Java Mail支持简化邮件发送
    Java Mail简化邮件发送+附件发送(源码奉上)
    java common practice to rethrow exceptions
    浅谈Java内存泄露
    全局样式
    求最大公约数和最小公倍数
    求所有水仙花数
    indexedDB数据库的使用
    fileReader读取文件
  • 原文地址:https://www.cnblogs.com/joe235/p/11242354.html
Copyright © 2020-2023  润新知