59 votes

Comment puis-je transmettre des données non-chaîne à une route nommée dans Flutter?

J'ai plusieurs écrans et j'utilise les Navigator . J'aimerais utiliser "itinéraires nommés", mais je dois également passer des chaînes (telles que des images) à mon prochain itinéraire.

Je ne peux pas utiliser pushNamed() parce que je ne peux pas lui transmettre de données autres que des chaînes.

Comment utiliser une route nommée + envoyer des données autres que des chaînes?

70voto

Rémi Rousselet Points 45139

MODIFIER:

Il est maintenant possible de passer des arguments complexes à Navigator.pushNamed :

 String id;
Navigator.pushNamed(context, '/users', arguments: id);
 

Il peut ensuite être utilisé dans onGenerateRoute pour personnaliser la construction de route avec ces arguments:

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

30voto

Yuriy Luchaninov Points 266

Vous pouvez utiliser le paramètre routes de votre application pour transmettre directement des arguments.

Comme ça:

   routes: {
    HomePage.route: (_) => HomePage(),
    DetailsPage.route: (context) =>
        DetailsPage(ModalRoute.of(context).settings.arguments),
  },
 

Dans ce cas, l'exemple complet ressemblera au suivant:

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

9voto

nilobarp Points 1996

À l'aide de onGenerateRoute il est facile de passer des arguments complexes sur la route de transition avec Navigator.pushNamed ou Navigator.pushReplacementNamed

Une configuration minimale pour montrer le concept serait

principal.dart

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

les itinéraires.dart

Dans l' _buildRoute méthode que nous avons vérifier le nom de l'itinéraire et de la fonte des arguments d'un type requis.

Un tirage dos, c'est que le type doit être défini avant de la main si nécessaire argument n'est pas un type simple.

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

Vues

liste.dart

Construire la route argument à l'aide d'un type défini, Article dans notre cas.

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

des détails.dart

Définir un type pour les arguments

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

3voto

devdanke Points 509

Le livre de recettes Flutter montre comment naviguer vers une nouvelle page et lui transmettre des données non chaîne.

Passer des données à la page suivante

J'ai commencé avec Navigator.pushedNamed() parce que c'était simple et que je n'avais aucune donnée à transmettre. Lorsque mes besoins ont changé et que je souhaitais transmettre des données, je suis passé à Navigator.push() .

Exemple:

 var nextPageData = {foo:'bar'};

Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => 
     MyNextPage(myData: nextPageData))
 );
 

1voto

Ravindra Bhanderi Points 461

Pour résoudre ce problème, j'ai développé le package

lien: https://pub.dartlang.org/packages/navigate

Cela donne beaucoup à votre attente et facile à utiliser

 Navigate.navigate(context,
                      "home",
                      transactionType:TransactionType.fromLeft , // optional
                      replaceRoute: ReplaceRoute.thisOne, //optional
                      arg: {"transactionType":TransactionType.fromLeft,"replaceRoute":ReplaceRoute.thisOne} //optional
                      );
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X