【问题标题】:Flutter - Push and Get value between routesFlutter - 在路由之间推送和获取价值
【发布时间】:2017-11-27 12:15:19
【问题描述】:

如何将绿色字符串从 HomePage 页面发送到 ContaPage 页面?

我觉得是Navigator.of(context).pushNamed('/conta/green');,但我不知道如何进入页面contagreen字符串

因此,通过获取字符串的值,我可以例如更改 ContaPageappBar 的背景颜色的颜色。

ma​​in.dart

import "package:flutter/material.dart";

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: "MyApp",
      home: new HomePage(),
      routes: <String, WidgetBuilder> {
        '/home': (BuildContext context) => new HomePage(),
        '/conta': (BuildContext context) => new ContaPage()
      },
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) => new Scaffold(
    appBar: new AppBar(
      backgroundColor: new Color(0xFF26C6DA),
    ),
    body: new ListView  (
      children: <Widget>[
        new FlatButton(
          child: new Text("ok"),
          textColor: new Color(0xFF66BB6A),               
          onPressed: () {
            Navigator.of(context).pushNamed('/conta');
          },
        ),
      ],
    )
  );
}

class ContaPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) => new Scaffold(
    appBar: new AppBar(
      backgroundColor: new Color(0xFF26C6DA),
    ), 
  );
}

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    您始终可以在您的主页中创建一个带有绿色的静态变量字符串作为它的值,并在您创建新的 ContaPage 时在您的路线中使用该值。像这样的:

    import "package:flutter/material.dart";
    
    void main() {
      runApp(new MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: "MyApp",
          home: new HomePage(),
          routes: <String, WidgetBuilder> {
            '/home': (BuildContext context) => new HomePage(),
            '/conta': (BuildContext context) => new ContaPage(HomePage.color)
          },
        );
      }
    }
    
    class HomePage extends StatelessWidget {
    
      static String color = "green";
    
      @override
      Widget build(BuildContext context) => new Scaffold(
        appBar: new AppBar(
          backgroundColor: new Color(0xFF26C6DA),
        ),
        body: new ListView  (
          children: <Widget>[
            new FlatButton(
              child: new Text("ok"),
              textColor: new Color(0xFF66BB6A),               
              onPressed: () {
                Navigator.of(context).pushNamed('/conta');
              },
            ),
          ],
        )
      );
    }
    
    class ContaPage extends StatelessWidget {
    
      ContaPage({this.color})
      String color;
    
      @override
      Widget build(BuildContext context) => new Scaffold(
        appBar: new AppBar(
          backgroundColor: new Color(0xFF26C6DA),
        ), 
      );
    }
    

    可能有更好的解决方案,但这首先出现在我的脑海中 :)

    【讨论】:

    • 但是如果我有3个FlatButton每一个发送一个颜色,我如何步进指定的每个颜色?
    • onPressed 方法如下所示: onPressed: () { color = "myNewColor" Navigator.of(context).pushNamed('/conta'); },
    • 您只需在导航前更改 onPressed 函数中的颜色即可。
    • 肯定不能把颜色改成静态的吧?
    【解决方案2】:

    您可以按需创建MaterialPageRoute 并将参数传递给ContaPage 构造函数。

    import "package:flutter/material.dart";
    
    void main() {
      runApp(new MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: "MyApp",
          home: new HomePage(),
        );
      }
    }
    
    class HomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) => new Scaffold(
        appBar: new AppBar(
          backgroundColor: new Color(0xFF26C6DA),
        ),
        body: new ListView  (
          children: <Widget>[
            new FlatButton(
              child: new Text("ok"),
              textColor: new Color(0xFF66BB6A),
              onPressed: () {
                Navigator.push(context, new MaterialPageRoute(
                  builder: (BuildContext context) => new ContaPage(new Color(0xFF66BB6A)),
                ));
              },
            ),
          ],
        )
      );
    }
    
    class ContaPage extends StatelessWidget {
      ContaPage(this.color);
      final Color color;
      @override
      Widget build(BuildContext context) => new Scaffold(
        appBar: new AppBar(
          backgroundColor: color,
        ),
      );
    }
    

    【讨论】:

    • 如果是popAndPushNamed,流程一样吗?
    • 只需拨打Navigator.pop(context),然后拨打Navigator.push(context, ...)。它做同样的事情。
    【解决方案3】:

    这有点晚了,但它可能会对某些人有所帮助。我认为最好的方法是使用flutter route项目fluro

    在全局范围内定义一些地方:

    final router = Router();
    

    然后定义路线

    var contaHandler = Handler(handlerFunc: (BuildContext context, Map<String, dynamic> params) {
      return ContaPage(color: params["color"][0]);
    });
    
    void defineRoutes(Router router) {
      router.define("/conta/:color", handler: contaHandler);
    }
    

    MaterialApp 中设置onGenerateRoute 以使用路由器生成器:

     new MaterialApp (
       ...
       nGenerateRoute: router.generator
       ...
     ),
    

    您必须在依赖项中添加荧光:

     dependencies:
         fluro: "^1.3.4"
    

    并通过以下方式或IDE方式进行包升级。

     flutter packages upgrade
    

    【讨论】:

    • 如果我有 json 对象怎么办?我正在尝试这个 navigateTo(context, '/detail_screen/$propertyObj', transition: TransitionType.native);但没有运气。它在 NextScreen 上给出错误。
    • @AnujSharma,试试json.encodejson.decode。实际上我的意思是将json作为字符串发送。
    • @AnujSharma 如果还没有解决,你可以试试stackoverflow.com/a/55325051/7784230
    【解决方案4】:

    Flutter官网上已经给出了更好的解决方案,如何使用:

    参数

    class ScreenArguments {
      final String title;
      final String message;
    
      ScreenArguments(this.title, this.message);
    }
    

    提取参数

    class ExtractArgumentsScreen extends StatelessWidget {
      static const routeName = '/extractArguments';
    
      @override
      Widget build(BuildContext context) {
        final ScreenArguments args = ModalRoute.of(context).settings.arguments;
        return Scaffold(
          appBar: AppBar(
            title: Text(args.title),
          ),
          body: Center(
            child: Text(args.message),
          ),
        );
      }
    }
    

    注册路线

    MaterialApp(
      //...
      routes: {
        ExtractArgumentsScreen.routeName: (context) => ExtractArgumentsScreen(),
        //...
      },     
    );
    

    导航

    Navigator.pushNamed(
          context,
          ExtractArgumentsScreen.routeName,
          arguments: ScreenArguments(
            'Extract Arguments Screen',
            'This message is extracted in the build method.',
          ),
        );
    

    link复制的代码。

    【讨论】:

    • 这是唯一对我有用的解决方案。我在颤振页面中看到的示例涉及onGeneratedRoute 的使用,但在我的情况下,在推送命名路由时从未调用过该事件。
    【解决方案5】:

    将数据从第一页传递到第二页

    在第一页

    // sending "Foo" from 1st page
    Navigator.push(context, MaterialPageRoute(builder: (_) => Page2("Foo")));
    

    在第二页。

    class Page2 extends StatelessWidget {
      final String string;
      Page2(this.string); // receiving "Foo" in 2nd
    }
    

    将数据从第二页传回第一页

    在第二页

    // sending "Bar" from 2nd
    Navigator.pop(context, "Bar");
    

    在第一页中,它与之前使用的相同,但几乎没有修改。

    // receiving "Bar" in 1st
    String received = await Navigator.push(context, MaterialPageRoute(builder: (_) => Page2("Foo")));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-09
      • 2021-01-16
      • 2023-02-14
      • 1970-01-01
      • 1970-01-01
      • 2019-06-21
      • 1970-01-01
      • 2019-01-10
      相关资源
      最近更新 更多