Flutter уже знал — Named Router может передавать параметры!

Flutter

В этой статье рассматриваются некоторые не-FlutterstableВерсия(2019年2月25日 为止), вы можете проверить соответствующие документы Flutter, чтобы проверить, синхронизированы ли новые функции.stableразветвление или переключение других ветвей (например,master) опыт

введение

Когда мы используем Flutter для разработки приложений, маршрутизация является обязательной.

Flutter предоставляет два способа маршрутизации, а именноNavigator.push() (пример) так же какNavigator.pushNamed() (пример).

У каждого из этих двух методов есть преимущества и недостатки:

  1. Navigator.push()
  • Преимущества: динамичность и большая степень свободы, возможность переходить на новые страницы различными способами анимации и передавать параметры новым страницам.
  • Недостатки: это приведет к избыточности кода и неудобно для обслуживания кода. (конечно можно инкапсулировать, здесь это не обсуждается)
  1. Navigator.pushNamed()
  • Преимущества: переход между страницами может быть выполнен одним предложением, подобно тому, как это делается в большинстве современных фреймворков.
  • Недостаток: нельзя передавать параметры! Параметры не могут быть переданы! Параметры не могут быть переданы!

выберите

В реальной разработке и применении мы также более склонныNamedметод маршрутизации.

Но единственным недостатком является то, что он не поддерживает передачу параметров, что действительно бесит.

На самом деле этот вопрос поднимался в Flutter’s Issues уже 16 лет, но этоIssueдо этого годаPRОтправлено(目前为止这个功能仅仅被合并进master分支并没有同步到bate或者stable)

Начать

  1. Сначала мы должны перейти к основной ветке

воплощать в жизньflutter channel masterа затем запустите командуflutter upgradeУбедитесь, что вы используете последнюю версию. Вы можете переключиться на основную ветку

  1. Создайте проект на флаттере
  2. мы здесьmain.dartслегка модифицированный
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(this.title),
      ),
      body: Center(
        child: GestureDetector(
          onTap: (){
            // TODO
          },
          child: Text("go next page with params"),
        ),
      ),
    );
  }
}


  1. Добавить вторую страницуpage.dart
import 'package:flutter/material.dart';

class Page extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Material(
      child: Center(
        child: Text("hi this is next page"),
      ),
    );
  }
}
  1. Добавить маршрут и перейти при передаче параметровmain.dart
import 'package:flutter/material.dart';
// 引入新页面
import 'page.dart';

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

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      // 处理Named页面跳转 传递参数
      onGenerateRoute: (RouteSettings setting) {
        if(setting.name == '/page') {
          return MaterialPageRoute(builder: (context) => Page(id: setting.arguments['id']));
        }
      },
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(this.title),
      ),
      body: Center(
        child: GestureDetector(
          onTap: (){
            // 进行Named页面跳转 传递参数
            Navigator.pushNamed(context, '/page', arguments: { "id": 1} );
          },
          child: Text("go next page with params"),
        ),
      ),
    );
  }
}


  1. Страница принимает параметрыpage.dart
import 'package:flutter/material.dart';

class Page extends StatelessWidget{
  Page({this.id});
  final int id;

  @override
  Widget build(BuildContext context) {
    return Material(
      child: Center(
        child: Text("hi this is next page, id is $id"),
      ),
    );
  }
}

Эффект

оптимизация

Здесь мы все ещеonGenerateRouteЧтобы справиться с нашим именованным прыжком, мы оптимизируем его.

(На данный момент нет возможности его обработать в роутах MaterialApp, причина видна в исходниках (один)(два))

Исходный код один: вызовwidget.pageRouteBuilderи пройти вsettings(argumentsсуществуетsettingsсередина)

Исходный код два:pageRouteBuilderжестко запрограммирован для созданияMaterialPageRoute,а такжеMaterialPageRouteне является правильнымsettingsпройти

поэтому мы можем толькоonGenerateRouteобработано в.(Надеюсь, официальный сайт можно будет и дальше оптимизировать, эмммм, подождем и увидим)

/**
 *   main.dart
 */
import 'package:flutter/material.dart';
// 引入新页面
import 'page.dart';

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

class MyApp extends StatelessWidget {
  // 定义路由信息
  final Map<String, Function> routes = {
    '/page': (context, {arguments}) => Page(arguments: arguments)
  };

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      // 处理Named页面跳转 传递参数
      onGenerateRoute: (RouteSettings settings) {
        // 统一处理
        final String name = settings.name;
        final Function pageContentBuilder = this.routes[name];
        if (pageContentBuilder != null) {
          final Route route = MaterialPageRoute(
              builder: (context) =>
                  pageContentBuilder(context, arguments: settings.arguments));
          return route;
        }
      },
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(this.title),
      ),
      body: Center(
        child: GestureDetector(
          onTap: () {
            // 进行Named页面跳转 传递参数
            Navigator.pushNamed(context, '/page', arguments: {'id': 123});
          },
          child: Text("go next page with params"),
        ),
      ),
    );
  }
}


/**
 *   page.dart
 */

import 'package:flutter/material.dart';

class Page extends StatelessWidget{
  Page({this.arguments});
  final Map arguments;

  @override
  Widget build(BuildContext context) {
    return Material(
      child: Center(
        child: Text("hi this is next page, id is ${arguments != null ? arguments['id'] : '0'}"),
      ),
    );
  }
}

Связанный код

flutter_new_feature