快速开始

最简单的使用是用 RoutesLocationBuilder 实现,这种方式产出的代码最少。对于导航场景较少的应用或者页面栈浅的应用(即页面很少堆叠在一起)来说,是很棒的选择。

class MyApp extends StatelessWidget {

final routerDelegate = BeamerDelegate(

locationBuilder: RoutesLocationBuilder(

routes: {

// Return either Widgets or BeamPages if more customization is needed

// 返回 Widgets 或 BeamPages(如果需要更多定制的话)

'/': (context, state, data) => HomeScreen(),

'/books': (context, state, data) => BooksScreen(),

'/books/:bookId': (context, state, data) {

// Take the path parameter of interest from BeamState

// 从 BeamState 获取路径参数

final bookId = state.pathParameters['bookId']!;

// Collect arbitrary data that persists throughout navigation

// 收集在整个导航过程中持续存在的任意数据

final info = (data as MyObject).info;

// Use BeamPage to define custom behavior

// 使用 BeamPage 来自定义行为

return BeamPage(

key: ValueKey('book-$bookId'),

title: 'A Book #$bookId',

popToNamed: '/',

type: BeamPageType.scaleTransition,

child: BookDetailsScreen(bookId, info),

);

}

},

),

);

@override

Widget build(BuildContext context) {

return MaterialApp.router(

routeInformationParser: BeamerParser(),

routerDelegate: routerDelegate,

);

}

}

RoutesLocationBuilder 会根据路径对 routes 进行选择和排序。 例如,导航到 /books/1 会匹配 routes 里的全部3个实体,然后把它们堆叠在一起。导航到 /books 会匹配routes 的前两个实体。

对应的页面被放入到 Navigator.pages 中,BeamerDelegate (重新)构建 Navigator ,在屏幕上显示选中的页面栈。

为什么我们有一个 locationBuilder ? BeamLocation 是什么?它的输出是什么?

BeamLocation 是一个实体,它基于它的 state 来决定哪个页面要进入到 Navigator.pages 里。locationBuilder 选择适当的 BeamLocation 来进一步处理收到的 RouteInformation 。 这大多数是通过验证 BeamLocation.pathPatterns 来实现。

RoutesLocationBuilder 返回 BeamLocation 的一个特殊类型 - RoutesBeamLocation,它有用于绝大多数常用的导航场景的实现。 如果 RoutesLocationBuilder 没有提供所需的行为或者足够的定制,可以扩展 BeamLocation 为进入到 Navigator.pages 的任意数量的页面栈来定义和组织行为。

深入阅读: BeamLocation [中文],BeamState[中文]。

导航

导航是用 “beam” 来完成的。可以认为是在应用中传送(beam)到其它地方。 类似于 Navigator.of(context).pushReplacementNamed('/my-route'),但是 Beamer 并不限于单个页面,或者是推入栈本身。 BeamLocation 创建页面的栈,当 beam 到某个页面时,页面会被构建。 Beaming 感觉像是同时使用了多个 Navigator 的 push/pop (入栈/出栈)方法。

// Basic beaming

Beamer.of(context).beamToNamed('/books/2');

// Beaming with an extension method on BuildContext

// 使用 BuildContext 的扩展方法 Beaming

context.beamToNamed('/books/2');

// Beaming with additional data that persist

// throughout navigation withing the same BeamLocation

// 用同一个 BeamLocation 的导航过程中的数据 Beaming。

context.beamToNamed('/book/2', data: MyObject());

导航返回

这里有两种返回的类型,即 reverse navigation(反转导航); 向上 和 反转时序.

向上 (从栈中弹出页面)

向上导航是指导航到当前页面栈的前一个页面。就是大家熟知的弹出,通过 Navigator 的 pop/maybePop 方法来完成。如果不指定其它处理,默认的 AppBar 的 BackButton 返回按钮会调用这个方法。

Navigator.of(context).maybePop();

反转时序 ( beam 到前一个状态)

反转时序导航会导航到前面访问过的任意地方。在深度链接的情况(例如:从 /authors/3 导航到 /books/2,而不是从 /books 导航到 /books/2)下,这和弹出是不一样的。 Beamer 在 beamingHistory 历史中保持着导航历史,所以它能够导航到 beamingHistory 中的前一个时间点的入口。这称作 “beam back” (回光返照?皮一下)。

Beamer.of(context).beamBack();

Android 返回按键

集成 beam 的 Android 返回按键通过在 MaterialApp.router 中设置 backButtonDispatcher 来实现。这个分发器需要指向同一个为routerDelegate 设置的 BeamerDelegate 的引用。

MaterialApp.router(

...

routerDelegate: beamerDelegate,

backButtonDispatcher: BeamerBackButtonDispatcher(delegate: beamerDelegate),

)

BeamerBackButtonDispatcher 会首先尝试 pop (弹出),如果弹出不可用,会改为 beamBack 。如果 beamBack 返回 false (没有地方可返回),Android 的返回按钮会关闭应用,也可能是返回前一个使用的应用(通过 deep-link (深度链接)打开当前应用)。 BeamerBackButtonDispatcher 可以配置为 alwaysBeamBack (意思是不会尝试 pop (弹出))或 fallbackToBeamBack (意思是不会尝试 beamBack)。

访问最近的 Beamer

要在组件中访问路由的属性(例如,用于构建 BookDetailsScreen 的 bookId )可以使用:

@override

Widget build(BuildContext context) {

final beamState = Beamer.of(context).currentBeamLocation.state as BeamState;

final bookId = beamState.pathParameters['bookId'];

...

}

使用 “Navigator 1.0”

注意 “Navigator 1.0”(命令式的 push/pop 和类似的函数)可以和 Beamer 一起使用。我们已经看到 Navigator.pop 用来向上导航。这告诉我们是在使用同样的 Navigator ,只是使用了不同的 API 。

用 Navigator.of(context).push (或任何类似的动作) 入栈不会反映到 BeamLocation 的状态,这意味着浏览器的 URL 不会改变。可以通过 Beamer.of(context).updateRouteInformation(...) 来只更新 URL 。当然在移动端使用 Beamer 时不会有这个问题,因为看不到 URL 。

通常,每个导航场景应该是可实现的声明式(定义页面栈),而不是命令式(入栈),但是做到这一点的难度会有所不同。

对于中级和高级的用法,现在介绍一些核心概念: BeamLocation 和 BeamState 。

核心概念

从最顶层来看,Beamer 是 Router 的包装,它使用 了自身的对 RouterDelegate 和 RouteInformationParser 的实现。Beamer 的目标是分离【用不同的状态为 Navigator.pages 的多个类来构建页面栈】的职责,代替所有页面栈使用一个全局状态。

例如,我们想要处理所有个人资料相关的页面栈如:

[ ProfilePage ] (个人资料页面),

[ ProfilePage, FriendsPage](个人资料页面,好友页面),

[ ProfilePage, FriendsPage, FriendDetailsPage ](个人资料页面,好友页面,好友详细页面),

[ ProfilePage, SettingsPage ](个人资料页面,设定页面),

用一些 “ProfileHandler” 来知道哪个状态对应哪个页面栈。类似地,我们想要一个 “ShopHandler” 来处理所有商店关联的页面栈。这些页面如:

[ ShopPage ](商店页面),

[ ShopPage, CategoriesPage ](商店页面,品类页面),

[ ShopPage, CategoriesPage, ItemsPage ](商店页面,品类页面,商品页面),

[ ShopPage, CategoriesPage, ItemsPage, ItemDetailsPage ](商店页面,品类页面,商品页面,商品详细页面),

[ ShopPage, ItemsPage, ItemDetailsPage ](商店页面,商品

相关阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: