命名路线的动画

时间:2018-10-08 08:35:11

标签: android animation routing flutter

在Flutter中,我们可以通过扩展PageRoute(或使用扩展该类的类)来自定义视图更改动画。

例如,我通过使用MaterialApplication来在CupertinoPageRoute中将动画更改为“滑动”:

Navigator.of(context).pushReplacement(
  CupertinoPageRoute(builder: (context) => Calendar()),
);

现在,我想通过使用main.dart文件中定义的命名视图来更改它:

return MaterialApp(
  title: 'Demo',
  theme: myTheme, // => Theme.of(context).copyWith(...)
  initialRoute: '/',
  routes: {
    '/': (context) => Login(),
    '/calendar': (context) => Calendar(),
  }
);

这样我就可以打电话

Navigator.of(context).pushReplacementNamed('/calendar');

这是IMO更清晰且与视图无关的东西。

这种方法的问题在于我无法定义PageRoute,因此无法自定义视图更改动画。

有办法吗?

2 个答案:

答案 0 :(得分:1)

您可以利用onGenerateRoute()

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  Route onGenerateRoute(RouteSettings settings) {
    Route page;
    switch (settings.name) {
      case "/":
        page = CupertinoPageRoute(builder: (context) => Login());
        break;
      case "/calendar":
        page = CupertinoPageRoute(builder: (context) => Calendar());
        break;
    }
    return page;
  }

  @override
  Widget build(BuildContext context) {
    return new WidgetsApp(
      onGenerateRoute: onGenerateRoute,
      initialRoute: "/",
    );
  }
}

让我们看一下Flutter代码本身。

有一个onGenerateRoute()提供的框架方法被调用来生成路由。

请查看以下摘录自框架中app.dart文件的摘录。

  Route<dynamic> _onGenerateRoute(RouteSettings settings) {
    final String name = settings.name;
    WidgetBuilder builder;
    if (name == Navigator.defaultRouteName && widget.home != null) {
      builder = (BuildContext context) => widget.home;
    } else {
      builder = widget.routes[name];
    }
    if (builder != null) {
      return new MaterialPageRoute<dynamic>(
        builder: builder,
        settings: settings,
      );
    }
    if (widget.onGenerateRoute != null)
      return widget.onGenerateRoute(settings);
    return null;
  }

如果routes:为给定名称提供了构建器,则默认情况下将使用MaterialPageRoute来生成路由。如果未提供,它将使用您的onGenerateRoute()方法生成它。

答案 1 :(得分:-1)

我接受了chemamolins的建议并以类似的方式解决了这个问题,但是使用了地图。

我“提取”了routes对象,并将其放在MaterialApp之外:

var routes = {
  '/': (context) => Login(),
  '/calendar': (context) => Calendar()
};

然后我在onGenerateRoute内部使用了它:

Widget build(BuildContext context) {
  var routes = {
    '/': (context) => Login(),
    '/calendar': (context) => Calendar()
  };

  return MaterialApp(
    title: 'Demo',
    theme: myTheme,
    initialRoute: '/',
    onGenerateRoute: (settings) {
      return CupertinoPageRoute(builder: (context) => routes[settings.name](context));
    }
  );
}