如何将非字符串数据传递给Flutter中的命名路由?

Set*_*add 34 dart flutter

我有很多屏幕,我正在使用Navigator.我想使用"命名路由",但我还需要将非字符串(如图像)传递给下一个路由.

我无法使用,pushNamed()因为我无法将非字符串数据传递给它.

如何使用命名路由+发送非字符串数据?

Rém*_*let 43

编辑:

现在可以将复杂的参数传递给Navigator.pushNamed:

String id;
Navigator.pushNamed(context, '/users', arguments: id);
Run Code Online (Sandbox Code Playgroud)

然后可以使用它来使用onGenerateRoute以下参数自定义路由构建:

MaterialApp(
  title: 'Flutter Hooks Gallery',
  onGenerateRoute: (settings) {
    final arguments = settings.arguments;
    switch (settings.name) {
      case '/users':
        if (arguments is String) {
          // the details page for one specific user
          return UserDetails(arguments);
        }
        else {
          // a route showing the list of all users
          return UserList();
        }
      default:
        return null;
    }
  },
);
Run Code Online (Sandbox Code Playgroud)

  • 以上答案仍然有效吗?我无法通过`RouteSettings`看到`arguments`属性... (2认同)
  • 它是最近添加的。您可能想要切换频道。 (2认同)
  • 不应该将`UserDetails` 和`UserList` 包装到`MaterialPageRoute` 中吗? (2认同)

San*_*ngh 26

通过使用地图

在推送参数时,您可以以地图形式推送参数,并且可以在提取它们时执行相同操作。

例如

推的同时

Navigator.of(context).pushNamed(
              'second',
              arguments: {
                'title':'This is a String',
                       or
                 'Fx': This could be any widget or Function
              }
Run Code Online (Sandbox Code Playgroud)

在提取目标页面中的参数时

final routes=ModalRoute.of(context).settings.arguments as Map<String,String>;

    return Scaffold(
      appBar: AppBar(
              title: Text(routes['title']),
              ),
      body: Container(
        child: Center(
          child: RaisedButton(
            child: Text("Back"),
            onPressed: ()=>Navigator.of(context).pop(),
          ),
        ),
      ),
    );

and choose your map accordingly accordingly
Run Code Online (Sandbox Code Playgroud)

  • 简单的非生成路由的最佳示例:) (3认同)

jon*_*ges 6

这里有许多巨大的解决方案,但是您的问题可以使用此库通过两行字面来解决:https : //pub.dev/packages/get

List users = [2,4,6,3]
Get.toNamed('/second', arguments: users);
Run Code Online (Sandbox Code Playgroud)

在第二条路线上

print(Get.arguments);
// out: [2,4,6,3]
Run Code Online (Sandbox Code Playgroud)

与其他解决方案相比,使用它的优势在于你可以通过参数传递任何东西,如果你愿意,甚至可以传递类实例,并且你可以从任何地方检索参数,包括在你的 UI 中,在你的块、控制器、你的提供者等中,无需将 onGenerateRoute 中的参数传递给类。


nil*_*arp 5

使用onGenerateRoute很容易传递路线过渡复杂的参数Navigator.pushNamedNavigator.pushReplacementNamed

展示概念的最小设置是

主镖

import 'package:flutter/material.dart';
import 'package:navigator/routes.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Navigation Demo',
      theme: ThemeData(
        primarySwatch: Colors.teal,
      ),
      onGenerateRoute: (RouteSettings settings) {
        return MaterialPageRoute(
          builder: (BuildContext context) => makeRoute(
                context: context,
                routeName: settings.name,
                arguments: settings.arguments,
              ),
          maintainState: true,
          fullscreenDialog: false,
        );
      },
    );
  }
}

Run Code Online (Sandbox Code Playgroud)

route.dart

在该_buildRoute方法中,我们检查路由名称,并将参数强制转换为必需的类型。

缺点是,如果必需的参数不是简单类型,则必须事先定义类型。

import 'package:flutter/material.dart';

import 'package:navigator/list.dart';
import 'package:navigator/details.dart';

Widget makeRoute(
    {@required BuildContext context,
    @required String routeName,
    Object arguments}) {
  final Widget child =
      _buildRoute(context: context, routeName: routeName, arguments: arguments);
  return child;
}

Widget _buildRoute({
  @required BuildContext context,
  @required String routeName,
  Object arguments,
}) {
  switch (routeName) {
    case '/':
      return ArticleList();
    case '/ArticleView':
      Article article = arguments as Article;
      return ArticleView(article: article);
    default:
      throw 'Route $routeName is not defined';
  }
}
Run Code Online (Sandbox Code Playgroud)

观看次数

list.dart

Article在我们的例子中,使用定义的类型构造route参数。

import 'package:flutter/material.dart';
import 'package:navigator/details.dart' show Article;

class ArticleList extends StatefulWidget {
  @override
  _ArticleListState createState() => _ArticleListState();
}

class _ArticleListState extends State<ArticleList> {
  List<Article> articles = [
    Article(
        id: 1,
        title: 'Article 1',
        author_name: 'Nilotpal',
        summary: 'Article 1 summary'),
    Article(
        id: 2,
        title: 'Article 2',
        author_name: 'Mike',
        summary: 'Article 2 summary'),
  ];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Articles'),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            ListTile(
              title: Text('${articles[0].title}'),
              subtitle: Text('by ${articles[0].author_name}'),
              onTap: () {
                Navigator.of(context)
                    .pushNamed('/ArticleView', arguments: articles[0]);
              },
            ),
            ListTile(
              title: Text('${articles[1].title}'),
              subtitle: Text('by ${articles[1].author_name}'),
              onTap: () {
                Navigator.of(context)
                    .pushNamed('/ArticleView', arguments: articles[1]);
              },
            ),
          ],
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

details.dart

定义参数的类型

import 'package:flutter/material.dart';

class Article {
  final int id;
  final String author_name;
  final String title;
  final String summary;

  Article(
      {@required this.id,
      @required this.author_name,
      @required this.title,
      @required this.summary});
}

class ArticleView extends StatelessWidget {
  final Article _article;

  ArticleView({@required Article article}) : _article = article;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('${_article.title}'),
      ),
      body: SafeArea(
        top: true,
        child: Center(
          child: Column(
            children: <Widget>[
              Text('${_article.author_name}'),
              Text('${_article.summary}'),
            ],
          ),
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 哎呀最小的设置。 (2认同)

Yur*_*nov 5

您可以使用routesApp 的参数直接传递参数。

像这样:

  routes: {
    HomePage.route: (_) => HomePage(),
    DetailsPage.route: (context) =>
        DetailsPage(ModalRoute.of(context).settings.arguments),
  },
Run Code Online (Sandbox Code Playgroud)

在这种情况下,完整的示例将如下所示:

import 'package:flutter/material.dart';

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

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          initialRoute: HomePage.route,
          routes: {
            HomePage.route: (_) => HomePage(),
            DetailsPage.route: (context) =>
                DetailsPage(ModalRoute.of(context).settings.arguments),
          },
        );
      }
    }

    class HomePage extends StatelessWidget {
      static const String route = '/';

      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Container(),
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              Navigator.pushNamed(context, '/details',
                  arguments: ScreenArguments(
                    'My Details',
                    'Some Message',
                  ));
            },
          ),
        );
      }
    }

    class DetailsPage extends StatelessWidget {
      static const String route = '/details';

      final ScreenArguments arguments;

      DetailsPage(this.arguments);

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

    class ScreenArguments {
      final String title;
      final String message;

      ScreenArguments(this.title, this.message);
    }
Run Code Online (Sandbox Code Playgroud)