美文网首页
Flutter页面/组件传值

Flutter页面/组件传值

作者: Leo丶Dicaprio | 来源:发表于2019-12-17 16:36 被阅读0次

    父子组件之间的传值

    父组件

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: "Test",
          home: Scaffold(
            appBar: AppBar(
              title: Text("Test"),
            ),
            body: MyText(
              str1: "传递的值", //向自定义的MyText类传值,格式:参数名称:参数值
            ),
          ),
        );
      }
    }
    
    class MyText extends StatelessWidget {
      const MyText({Key key,@required this.str1}) : super(key: key);  //接收传递过来的值,使用@required修饰,表示为必传参数
      final String str1;  //定义接收参数
    
      @override
      Widget build(BuildContext context) {
        return Text(str1);
      }
    }
    

    页面导航打开新页面和返回新页面

    import 'package:flutter/material.dart';
    
    void main(){
      runApp(
        MaterialApp(
          title: "导航演示",
          home: FirstScreen(),
        )
      );
    }
    
    class FirstScreen extends StatelessWidget {
      const FirstScreen({Key key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Container(
          child: Scaffold(
            appBar: AppBar(title: Text("页面一"),),
            body: Center(
              child: RaisedButton(
                onPressed: (){
                  Navigator.push(context, MaterialPageRoute(
                    builder: (context) => SecondScreen()
                  ));  //第一个参数是上下文,第二个参数是路由参数
                },
                child: Text("打开新视图"),
              ),
            ),
          )
        );
      }
    }
    
    class SecondScreen extends StatelessWidget {
      const SecondScreen({Key key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text("页面二"),),
          body: Center(
            child: RaisedButton(
              child: Text("返回"),
              onPressed: (){
                Navigator.pop(context);
              },
            ),
          ),
        );
      }
    }
    

    导航之间的传值

    import 'package:flutter/material.dart';
    
    /**
     * 建立一个model类
     */
    class ProductModel{
      final String title; //商品标题
      final String desc;  //商品详情
      ProductModel(this.title,this.desc);  //使用构造函数
    }
    
    void main() {
      runApp(MaterialApp(
        title: "导航之间的传值",
        home: FirstController(
          /**
           * 为FirstController的 models 属性赋值,
           * 传递的是一个数组,数组中都是ProductModel类,
           * ProductModel有两个属性,所以传递形参传递两个
           */
          models:List.generate(20, (i)=>ProductModel("商品 $i","商品 $i 的描述 $i"))
        ),
      ));
    }
    
    class FirstController extends StatelessWidget {
      
      final List<ProductModel> models;  //FirstController的属性,
      FirstController({Key key,@required this.models}):super(key:key);  //为属性models接收值
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text("页面一"),),
          body: ListView.builder(         //创建一个列表
            itemCount: models.length,
            itemBuilder: (BuildContext context, int index) {
            return ListTile(
              leading: Icon(Icons.iso),
              title: Text(models[index].title),
              onTap: (){              //cell的响应方法,点击cell会执行这个方法
                Navigator.push(context, MaterialPageRoute(    //导航打开新视图
                  builder: (context) => SecondController(model:models[index]) //打开第二个页面,并传值,传递值的名称是model
                ));
              },
            );
           },
          ),
        );
      }
    }
    
    class SecondController extends StatelessWidget {
    
      final ProductModel model; //SecondController的model属性
      SecondController({Key key,@required this.model}):super(key : key);  //接收传递过来的值
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text("页面二"),),
          body: Center(child: Text(model.title),),
        );
      }
    }
    

    返回页面传值

    创建一个TipRoute路由,它接受一个提示文本参数,负责将传入它的文本显示在页面上,另外TipRoute中我们添加一个“返回”按钮,点击后在返回上一个路由的同时会带上一个返回参数,下面我们看一下实现代码。

    class TipRoute extends StatelessWidget {
      TipRoute({
        Key key,
        @required this.text,  // 接收一个text参数
      }) : super(key: key);
      final String text;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("提示"),
          ),
          body: Padding(
            padding: EdgeInsets.all(18),
            child: Center(
              child: Column(
                children: <Widget>[
                  Text(text),
                  RaisedButton(
                    onPressed: () => Navigator.pop(context, "我是返回值"),
                    child: Text("返回"),
                  )
                ],
              ),
            ),
          ),
        );
      }
    }
    

    下面是打开新路由TipRoute的代码:

    class RouterTestRoute extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Center(
          child: RaisedButton(
            onPressed: () async {
              // 打开`TipRoute`,并等待返回结果
              var result = await Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) {
                    return TipRoute(
                      // 路由参数
                      text: "我是提示xxxx",
                    );
                  },
                ),
              );
              //输出`TipRoute`路由返回结果
              print("路由返回值: $result");
            },
            child: Text("打开提示页"),
          ),
        );
      }
    }
    

    命名路由

    定义路由的名称,使用路由名称打开视图

    import 'package:flutter/material.dart';
    
    void main(){
      runApp(
        MaterialApp(
          title: "导航演示",
          routes: {         //命名路由,1,注册路由表
            "second_page": (context) => SecondScreen()
          },
          home: FirstScreen(),
        )
      );
    }
    
    class FirstScreen extends StatelessWidget {
      const FirstScreen({Key key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Container(
          child: Scaffold(
            appBar: AppBar(title: Text("页面一"),),
            body: Center(
              child: RaisedButton(
                onPressed: (){
                 Navigator.pushNamed(context, "second_page"); //2,就可以使用命名的路由打开新视图了
                },
                child: Text("打开新视图"),
              ),
            ),
          )
        );
      }
    }
    
    class SecondScreen extends StatelessWidget {
      const SecondScreen({Key key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text("页面二"),),
          body: Center(
            child: RaisedButton(
              child: Text("返回"),
              onPressed: (){
                Navigator.pop(context);
              },
            ),
          ),
        );
      }
    }
    

    命名路由传参

    import 'package:flutter/material.dart';
    
    void main(){
      runApp(
        MaterialApp(
          title: "导航演示",
          routes: {         //命名路由,1,注册路由表
            "second_page": (context) => SecondScreen()
          },
          home: FirstScreen(),
        )
      );
    }
    
    class FirstScreen extends StatelessWidget {
      const FirstScreen({Key key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Container(
          child: Scaffold(
            appBar: AppBar(title: Text("页面一"),),
            body: Center(
              child: RaisedButton(
                onPressed: (){
                 Navigator.of(context).pushNamed("second_page",arguments:"页面传值",); //2,使用命名的路由打开新视图,并传值
                },
                child: Text("打开新视图"),
              ),
            ),
          )
        );
      }
    }
    
    class SecondScreen extends StatelessWidget {
      const SecondScreen({Key key}) : super(key: key);
      
      @override
      Widget build(BuildContext context) {
    
        var value = ModalRoute.of(context).settings.arguments; //3.在build方法中,接收传递过来的值
    
        return Scaffold(
          appBar: AppBar(title: Text("页面二"),),
          body: Center(
            child:Column(
              children: <Widget>[
                Text(value),
                FlatButton(
                  child: Text("返回"),
                  onPressed: (){
                    Navigator.pop(context);
                  },
                )
              ],
            ),
          ),
        );
      }
    }
    

    路由生成钩子

    可以在onGenerateRoute方法中做路由判断,比如判断用户是否有token打开不同的页面等等

    import 'package:flutter/material.dart';
    
    void main(){
      runApp(
        MaterialApp(
          title: "导航演示",
          routes: {
            // "two_page":(context) => SecondScreen(),      //注意,使用onGenerateRoute时,不能注册routes,否则会不执行onGenerateRoute方法
          },
          onGenerateRoute: (RouteSettings setting){         //1,使用navigator.pushname方法时,在未找到路由名称,会执行这个里面的方法
            // setting.isInitialRoute; bool类型 是否初始路由
            print(setting.name);  //要跳转的路由名key
            return PageRouteBuilder(
                pageBuilder: (BuildContext context, _, __) {
                //这里为返回的Widget
                  switch (setting.name) {   //判断,如果是跳转路由名称是“two_page”,则返回SecondScreen()这个类
                    case "two_page":
                      return SecondScreen();
                      break;
    
                    default:
                      return FirstScreen();
                  }
                },
                opaque: false,
                //跳转动画
                transitionDuration: new Duration(milliseconds: 200),
                transitionsBuilder:
                    (___, Animation<double> animation, ____, Widget child) {
                  return new FadeTransition(
                    opacity: animation,
                    child: new ScaleTransition(
                      scale: new Tween<double>(begin: 0.5, end: 1.0)
                          .animate(animation),
                      child: child,
                    ),
                  );
                });
          },
          home: FirstScreen(),
        )
      );
    }
    
    class FirstScreen extends StatelessWidget {
      const FirstScreen({Key key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Container(
          child: Scaffold(
            appBar: AppBar(title: Text("页面一"),),
            body: Center(
              child: RaisedButton(
                onPressed: (){
                  Navigator.of(context).pushNamed("two_page",arguments: "传递参数"); //2,打开新页面,传递参数
                },
                child: Text("打开新视图"),
              ),
            ),
          )
        );
      }
    }
    
    class SecondScreen extends StatelessWidget {
      const SecondScreen({Key key}) : super(key: key);
      @override
      Widget build(BuildContext context) {
    
        var value = ModalRoute.of(context).settings.arguments;  //3,接收上个页面传递对参数
    
        return Scaffold(
          appBar: AppBar(title: Text("页面二"),),
          body: Center(
            child:Column(
              children: <Widget>[
                // Text(value),
                FlatButton(
                  child: Text("返回"),
                  onPressed: (){
                    Navigator.pop(context);
                  },
                )
              ],
            ),
          ),
        );
      }
    }
    

    相关文章

      网友评论

          本文标题:Flutter页面/组件传值

          本文链接:https://www.haomeiwen.com/subject/jhhmdctx.html