【问题标题】:Flutter - Get data using pushNameFlutter - 使用 pushName 获取数据
【发布时间】:2019-10-28 07:58:38
【问题描述】:

我正在尝试使用 pushName 发送数据。然后我尝试让这些数据显示在 Toast 消息中。

推送名

Navigator.pushNamed(
                            context,
                            '/navigator',
                            arguments: <String, String>{
                              'instalation': widget.instalation,
                              'message': DemoLocalizations.of(context)
                                      .text('cancel-message') +
                                  " " +
                                  widget.datameterValue.toString(),
                            },
                          );

尝试检索数据

        class Navigation extends StatefulWidget {
          final ConnectionPage args;
      Navigation({Key key, this.message, this.instalation, this.args}) : super(key: key);
    }

    class _NavigationState extends State<Navigation> {
  void initState() {
      super.initState();
        print(widget.args); //NULL

    final snackBar = SnackBar(
      duration: Duration(seconds: 5),
      content: Text(widget.args.messsage+ '.', textAlign: TextAlign.center),
      backgroundColor: Colors.red[700],
    );
    key.currentState.showSnackBar(snackBar);
    }
}

问题:返回 null。

那么:使用 pushName 获取数据的正确方法是什么?在文档中显示我们如何获取数据inside Scaffold,但我需要在 initState 中获取数据。

更新

路线

routes: {
    '/login': (context) => LoginPage(),
    '/navigator': (context) => Navigation(),
    '/home': (context) => HomePageScreen(),
    '/connect': (context) => ConnectionPage(),
  },  

更新 2

我尝试这样的事情

 Navigator.pushNamed(
      context,
      '/navigator',
      arguments: Navigation(
          instalation: widget.instalation,
          message: DemoLocalizations.of(context)
         .text('cancel-message') +
         " " +
         widget.datameterValue.toString(),
     ),
);

【问题讨论】:

  • 您好,您可以附上您用来管理命名路由的代码吗?
  • 用路线更新。

标签: flutter


【解决方案1】:

要在 initState 中执行此操作,您需要 WidgetsBinding.instance.addPostFrameCallbackModalRoute.of(context).settings.arguments
演示通过arguments: {'instalation': "123", "message": "456"}
您可以在下面看到完整的代码和工作演示图片

code sn -p 使用 push

    Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => ExtractArgumentsScreen(),
                    // Pass the arguments as part of the RouteSettings. The
                    // ExtractArgumentScreen reads the arguments from these
                    // settings.
                    settings: RouteSettings(
                      arguments: {'instalation': "123", "message": "456"},
                    ),
                  ),
                );


@override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      final routeArgs1 =
          ModalRoute.of(context).settings.arguments as Map<String, String>;
      final instalation = routeArgs1['instalation'];
      final message = routeArgs1['message'];
      print('instalation ${instalation}');
      print('message ${message}');

      key.currentState
          .showSnackBar(SnackBar(content: Text(message)));
    });
  }

代码 sn-p 使用 Navigator.pushNamed

return MaterialApp(
      // Provide a function to handle named routes. Use this function to
      // identify the named route being pushed, and create the correct
      // Screen.
      routes: {
        '/extractArguments': (context) => ExtractArgumentsScreen(),
      },

...

Navigator.pushNamed(
                  context,
                  ExtractArgumentsScreen.routeName,
                  arguments: {'instalation': "123", "message": "456"},
                );

工作演示

完整代码

    import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // Provide a function to handle named routes. Use this function to
      // identify the named route being pushed, and create the correct
      // Screen.
      routes: {
        '/extractArguments': (context) => ExtractArgumentsScreen(),
      },
      onGenerateRoute: (settings) {
        // If you push the PassArguments route
        if (settings.name == PassArgumentsScreen.routeName) {
          // Cast the arguments to the correct type: ScreenArguments.
          final ScreenArguments args = settings.arguments;

          // Then, extract the required data from the arguments and
          // pass the data to the correct screen.
          return MaterialPageRoute(
            builder: (context) {
              return PassArgumentsScreen(
                title: args.title,
                message: args.message,
              );
            },
          );
        }
      },
      title: 'Navigation with Arguments',
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Screen'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            // A button that navigates to a named route that. The named route
            // extracts the arguments by itself.
            RaisedButton(
              child: Text("Navigate to screen that extracts arguments"),
              onPressed: () {
                // When the user taps the button, navigate to the specific route
                // and provide the arguments as part of the RouteSettings.
                 Navigator.pushNamed(
                  context,
                  ExtractArgumentsScreen.routeName,
                  arguments: {'instalation': "123", "message": "456"},
                );
                /*Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => ExtractArgumentsScreen(),
                    // Pass the arguments as part of the RouteSettings. The
                    // ExtractArgumentScreen reads the arguments from these
                    // settings.
                    settings: RouteSettings(
                      arguments: {'instalation': "123", "message": "456"},
                    ),
                  ),
                );*/

              },
            ),
            // A button that navigates to a named route. For this route, extract
            // the arguments in the onGenerateRoute function and pass them
            // to the screen.
            RaisedButton(
              child: Text("Navigate to a named that accepts arguments"),
              onPressed: () {
                // When the user taps the button, navigate to a named route
                // and provide the arguments as an optional parameter.
                Navigator.pushNamed(
                  context,
                  PassArgumentsScreen.routeName,
                  arguments: ScreenArguments(
                    'Accept Arguments Screen',
                    'This message is extracted in the onGenerateRoute function.',
                  ),
                );
              },
            ),
          ],
        ),
      ),
    );
  }
}

// A Widget that extracts the necessary arguments from the ModalRoute.
class ExtractArgumentsScreen extends StatefulWidget {
  static const routeName = '/extractArguments';

  @override
  _ExtractArgumentsScreenState createState() => _ExtractArgumentsScreenState();
}

class _ExtractArgumentsScreenState extends State<ExtractArgumentsScreen> {
  final GlobalKey<ScaffoldState> key = new GlobalKey<ScaffoldState>();

  final snackBar = SnackBar(
    duration: Duration(seconds: 5),
    content: Text("message" + '.', textAlign: TextAlign.center),
    backgroundColor: Colors.red[700],
  );

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      final routeArgs1 =
          ModalRoute.of(context).settings.arguments as Map<String, String>;
      final instalation = routeArgs1['instalation'];
      final message = routeArgs1['message'];
      print('instalation ${instalation}');
      print('message ${message}');

      key.currentState
          .showSnackBar(SnackBar(content: Text(message)));
    });
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
  }

  @override
  Widget build(BuildContext context) {
    // Extract the arguments from the current ModalRoute settings and cast
    // them as ScreenArguments.
    final routeArgs =
        ModalRoute.of(context).settings.arguments as Map<String, String>;
    final instalation = routeArgs['instalation'];
    final message = routeArgs['message'];

    return Scaffold(
      key: key,
      appBar: AppBar(
        title: Text(' ${routeArgs['code']} '),
      ),
      body: Column(
        children: <Widget>[
          Center(
            child: Text('instalation ${instalation}'),
          ),
          RaisedButton(
            onPressed: () {
              key.currentState.showSnackBar(snackBar);
            },
          ),
        ],
      ),
    );
  }
}

// A Widget that accepts the necessary arguments via the constructor.
class PassArgumentsScreen extends StatelessWidget {
  static const routeName = '/passArguments';

  final String title;
  final String message;

  // This Widget accepts the arguments as constructor parameters. It does not
  // extract the arguments from the ModalRoute.
  //
  // The arguments are extracted by the onGenerateRoute function provided to the
  // MaterialApp widget.
  const PassArgumentsScreen({
    Key key,
    @required this.title,
    @required this.message,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: Center(
        child: Text(message),
      ),
    );
  }
}

// You can pass any object to the arguments parameter. In this example,
// create a class that contains both a customizable title and message.
class ScreenArguments {
  final String title;
  final String message;

  ScreenArguments(this.title, this.message);
}

【讨论】:

  • 我更新了问题。我可以做类似于我放在更新中的代码吗?
【解决方案2】:

所以,我看到您使用的是简单的 routes 方法。

为了提取路由参数,您需要为您的 MaterialApp(或者 Cupertino,我猜)提供一个 onGenerateRoute 函数。

你可以在here找到一个详尽的例子,所以我不会过多地回答这个问题。

希望这能解决您的问题,祝您编码愉快!

【讨论】:

  • onGenerateRoute 在 MaterialApp 中工作,这不是我需要的。我需要检索 pushName 参数的视图是 StatefulWidget。
猜你喜欢
  • 2019-06-19
  • 2021-01-30
  • 2021-01-18
  • 2021-04-17
  • 2021-04-04
  • 2020-09-05
  • 2021-12-18
  • 2020-09-12
  • 2020-10-18
相关资源
最近更新 更多