gpt4 book ai didi

routing - 用 flutter 嵌套路由

转载 作者:IT老高 更新时间:2023-10-28 13:49:57 66 4
gpt4 key购买 nike

我正在尝试为以下问题找出良好的架构解决方案:我有以下 一级 路线,也可以称为 布局:

/onboarding/* -> Shows onboarding layout
/dashboard/* -> Shows dashboard layout
/overlay/* -> shows slide up overlay layout
/modal/* -> shows modal layout

根据他/她的身份验证状态、操作等将用户路由到其中的每一个。我正确地理解了这个阶段。

当我想使用可以称为 页面二级路由时出现问题,例如

/onboarding/signin -> Shows onboarding layout, that displays signin route
/onboarding/plan -> Shows onboarding layout, that displays plan options
/modal/plan-info -> Shows modal layout, over previous page (/onboarding/plan) and displays plan-information page.

我怎样才能最好地定义/组织这些,以便我可以有效地路由到它们显示的布局和页面?请注意,每当我在一个布局中路由页面时,布局都不会改变,但我想根据路由在其中更改内容(页面)。

到目前为止,我实现了以下目标

import "package:flutter/widgets.dart";
import "package:skimitar/layouts/Onboarding.dart";
import "package:skimitar/layouts/Dashboard.dart";

Route generate(RouteSettings settings) {
Route page;
switch (settings.name) {
case "/onboarding":
page = new PageRouteBuilder(pageBuilder: (BuildContext context,
Animation<double> animation, Animation<double> secondaryAnimation) {
return new Onboarding();
});
break;
case "/dashboard":
page = new PageRouteBuilder(pageBuilder: (BuildContext context,
Animation<double> animation, Animation<double> secondaryAnimation) {
return new Dashboard();
});
break;
}
return page;
}

/* Main */
void main() {
runApp(new WidgetsApp(
onGenerateRoute: generate, color: const Color(0xFFFFFFFFF)));
}

这路由到登机和仪表板布局(现在只是简单的容器包装文本)。我也相信我可以在后面使用 PageRouteBuilder 来动画路线之间的过渡?现在我需要弄清楚如何在登机和仪表板上安装类似 nested secondary router 的东西。

下面是我想要实现的视觉表示,我需要能够成功地路由蓝色和红色位。在这个例子中,只要我们在 /dashboard 下,蓝色位(布局)就不会改变,但是当我们从 /dashboard/home 导航到 /仪表板/统计数据 红色位(页面)应该淡出并随着新内容淡入。如果我们从 /dashboard/home 导航到 /onboarding/home,红色位(布局)应该会随着它当前事件的页面一起消失并显示新的布局入职,故事还在继续。

enter image description here

编辑我用下面概述的方法取得了一些进展,基本上我将确定我的 runApp 内的布局并声明新的 WidgetsApp和每个布局内的路线。它似乎有效,但有一个问题,当我点击“注册”时,我被重定向到正确的页面,但我也可以看到它下面的旧页面。

ma​​in.dart

import "package:flutter/widgets.dart";
import "package:myProject/containers/layouts/Onboarding.dart";

/* Main */
void main() {
runApp(new Onboarding());
}

Onboarding.dart

import "package:flutter/widgets.dart";
import "package:myProject/containers/pages/SignIn.dart";
import "package:myProject/containers/pages/SignUp.dart";
import "package:myProject/services/helpers.dart";

/* Onboarding router */
Route onboardingRouter(RouteSettings settings) {
Route page;
switch (settings.name) {
case "/":
page = buildOnboardingRoute(new SignIn());
break;
case "/sign-up":
page = buildOnboardingRoute(new SignUp());
break;
default:
page = buildOnboardingRoute(new SignIn());
}
return page;
}

class Onboarding extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Container(
decoration: new BoxDecoration(
color: const Color(0xFF000000),
image: new DecorationImage(
image: new AssetImage("assets/images/background-fire.jpg"),
fit: BoxFit.cover)),
child: new WidgetsApp(
onGenerateRoute: onboardingRouter, color: const Color(0xFF000000)),
);
}
}

SignUp.dart

import "package:flutter/widgets.dart";

class SignUp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Center(
child: new Text("Sign Up",
style: new TextStyle(color: const Color(0xFFFFFFFF))));
}
}

helpers.dart

import "package:flutter/widgets.dart";

Route buildOnboardingRoute(Widget page) {
return new PageRouteBuilder(
opaque: true,
pageBuilder: (BuildContext context, _, __) {
return page;
});
}

最佳答案

虽然在技术上可以嵌套“导航器”,但此处不推荐这样做(因为它会破坏 Hero 动画)

您可以使用 onGenerateRoute构建嵌套的“路线”,在路线“/dashboard/profile”的情况下,构建一棵树WidgetApp > Dashboard > Profile .我认为这就是您想要实现的目标。

结合高阶函数,你可以拥有创建 onGenerateRoute 的东西给你。

提供代码流的线索:NestedRoute忽略布局的确切构建,让它在 builder 中方法(例如 builder: (child) => new Dashboard(child: child),)。调用 buildRoute 时方法我们将生成 PageRouteBuilder对于此页面的实例,但让 _build管理 Widgets 的创建.在 _build我们要么使用builder原样 - 或者让它膨胀子路由,通过调用请求的子路由,调用它自己的 _build .完成后,我们将使用构建的子路由作为构建器的参数。长话短说,您递归地深入到更多路径级别以构建路径的最后一级,然后让它从递归中上升并将结果用作外部级别的参数等等。

BuildNestedRoutes为您完成这项肮脏的工作并解析 NestedRoutes 的列表建立必要的RouteSettings .

所以,从下面的例子中

例子:

@override
Widget build(BuildContext context) {
return new MaterialApp(
initialRoute: '/foo/bar',
home: const FooBar(),
onGenerateRoute: buildNestedRoutes(
[
new NestedRoute(
name: 'foo',
builder: (child) => new Center(child: child),
subRoutes: [
new NestedRoute(
name: 'bar',
builder: (_) => const Text('bar'),
),
new NestedRoute(
name: 'baz',
builder: (_) => const Text('baz'),
)
],
),
],
),
);
}

在这里,您只需定义嵌套路由(名称 + 关联组件)。和NestedRoute类(class) + buildNestedRoutes方法是这样定义的:

typedef Widget NestedRouteBuilder(Widget child);

@immutable
class NestedRoute {
final String name;
final List<NestedRoute> subRoutes;
final NestedRouteBuilder builder;

const NestedRoute({@required this.name, this.subRoutes, @required this.builder});

Route buildRoute(List<String> paths, int index) {
return new PageRouteBuilder<dynamic>(
pageBuilder: (_, __, ___) => _build(paths, index),
);
}

Widget _build(List<String> paths, int index) {
if (index > paths.length) {
return builder(null);
}
final route = subRoutes?.firstWhere((route) => route.name == paths[index], orElse: () => null);
return builder(route?._build(paths, index + 1));
}
}

RouteFactory buildNestedRoutes(List<NestedRoute> routes) {
return (RouteSettings settings) {
final paths = settings.name.split('/');
if (paths.length <= 1) {
return null;
}
final rootRoute = routes.firstWhere((route) => route.name == paths[1]);
return rootRoute.buildRoute(paths, 2);
};
}

这样,您的FooBar组件不会与您的路由系统紧密耦合;但仍然有嵌套路线。它比将您的路线分发到各处更具可读性。而且您可以轻松添加一个新的。

关于routing - 用 flutter 嵌套路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48098085/

66 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com