我不明白为什么有人要使用命名的路线,Navigator.pushNamed()而不是在正常的 方式用Navigator.push()。
该教程页指出:
如果我们需要在应用程序的许多部分导航到同一个屏幕,这可能会导致代码重复。在这些情况下,定义“命名路线”并使用命名路线进行导航会很方便
使用简单路由时将如何生成重复以及如何使用命名路由消除重复?
我不明白有什么区别
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
Run Code Online (Sandbox Code Playgroud)
从
Navigator.pushNamed(context, '/second');
Run Code Online (Sandbox Code Playgroud)
在重复的情况下。
我需要获取我当前的路线名称。我习惯于在每个页面中GlobalKey创建。所以我创建:navigatorSeviceNavigator.of(context)navKey
class Keys {
static final GlobalKey<NavigatorState> navKey = GlobalKey<NavigatorState>();
}
Run Code Online (Sandbox Code Playgroud)
当我想重定向到另一个页面时,我会编写Keys.navKey.currentState.pushNamed()或pushReplacementNamed其他一些方法。
我想知道我在 Interceptor 中的当前路线,在那里我没有上下文。
在颤振中,我有一个用例,我想在屏幕顶部返回相同的路线(如果它已经存在),否则推送新路线。
例如,当前堆栈:(A -> B -> C -> D最顶层)
如果我推 B,我只想A -> C -> D -> B。我想将 B 及其状态带到前面。
我浏览了文档,但找不到执行此操作的方法。有人想出办法做到这一点吗?
Flutter Navigator 2.0 的主要机制之一是 RouterDelegate > build > Navigator 中的 onPopPage 函数。但是,我不明白 route.didPop(result) 何时返回 false。
我们可以使用John Ryan 的著名例子来说明我的问题。他的演示代码。
onPopPage: (route, result) {
if (!route.didPop(result)) {
return false;
}
// Update the list of pages by setting _selectedBook to null
_selectedBook = null;
show404 = false;
notifyListeners();
return true;
},
Run Code Online (Sandbox Code Playgroud)
在我所有的测试中,使用 AppBar 自动生成的后退按钮,route.didPop(result) 返回 true。
文档保持不变:
bool didPop(dynamic result)
package:flutter/src/widgets/navigator.dart
A request was made to pop this route. If the route can handle it internally (e.g. because …Run Code Online (Sandbox Code Playgroud) 我正在使用 Navigator 的声明式方法:
Navigator(
pages: [
MaterialPage(child: _screen),
],
onPopPage: (route, result) {
return route.didPop(result);
},
);
Run Code Online (Sandbox Code Playgroud)
如何在屏幕之间添加过渡?
因为我在不同的上下文中重复使用相同的组件,所以不需要的英雄动画显示在错误的过渡中,并且我的应用程序看起来非常故障。
这发生在一个相当普通的项目中,使用MaterialApp和pushNamed进行导航。
如何在特定转换中启用或禁用这些动画?
我正在使用带有嵌套路由器的 Flutter Navigator 2.0 - 有一个通过调用创建的主路由器,MaterialApp.router()以及使用适当的 RouterDelegates 创建为小部件的子路由器Router()(子路由器用作底部导航的页面)。
在当前的用例中,我想使用深层链接打开嵌套路由器内的页面之一,因此我按照说明进行配置:
RouteInformationParser将其解析为我自己的模型PlatformRouteInformationProvider通知所有嵌套路由器有关路由更改的信息当应用程序位于前台时(在启动屏幕上),一切正常 - 我收到一个 PushRoute 事件,并且根和嵌套Router小部件正确处理深层链接。但是,当应用程序未启动时,我没有收到设置为我的深层链接的初始路由,并且我得到默认值,空RouteInformation即空。为什么会发生这种情况?这是我的代码示例:
Android Manifest 中的FlutterMainActivity配置:
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:windowSoftInputMode="adjustResize">
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme" />
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- For deeplinking -->
<meta-data
android:name="flutter_deeplinking_enabled"
android:value="true" />
<!-- Accepts links in format myapp://*.myapp.com/ -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" …Run Code Online (Sandbox Code Playgroud) 我是 Flutter 中的 Navigator 2.0 新手,现在我尝试使用声明性方法实现 BottomSheet 行为。不幸的是,我只能想出一个相当麻烦的方法来做到这一点,所以我想知道是否有更简单的方法。
我正在构建一个购物应用程序,当用户点击列表中的项目时,我想显示从屏幕底部滑出的项目详细信息卡,使上一页变暗(如图所示)。我还想允许 url 支持,以便/item/id打开主页,然后在其上显示详细信息卡。
因此,我认为如何做到这一点是使用 和 推送(或在pagesNavigator 2.0 的情况下添加到 Navigator 的数组)自定义非不透明页面,没有过渡动画,然后使用动画控制器手动设置变暗和滑动动画。但这种方法似乎不自然(说实话,真的让我害怕),而且我仍然不清楚在这种情况下如何处理后退按钮(我是否需要以某种方式通知页面从 Navigator 播放关闭动画,这是方法吗?做这个?)。TransitionDelegatePageRouteBuilderonPopPage
如果有人有实现类似功能的经验,我将非常感谢分享!或者也许您想出了更优雅的解决方案,然后告诉我,我会尝试一下!谢谢!
我的应用程序结构可以是这样的:
home/folder/:fid/player
home/folder/:fid/folder/:fid/player
home/folder/:fid/folder/:fid/folder/:fid/player
Run Code Online (Sandbox Code Playgroud)
具有可以打开其他文件夹的嵌套文件夹(文件夹可以包含在播放器中播放的音频文件)等
这可以用 go router 实现吗?我尝试做这样的事情:
home/folder/:fid/folder2/:f2id/player
Run Code Online (Sandbox Code Playgroud)
但它变得非常混乱。我的路由器目前看起来像这样
final router = GoRouter(
routes: [
GoRoute(
path: HomePath,
builder: (context, state) => HomeWrapperWidget(),
routes: [
GoRoute(
path: 'session/:sid',
routes: [
GoRoute(
path: 'player',
pageBuilder: (context, state) =>
getPlayerMaterialPage(state),
)
],
pageBuilder: (context, state) =>
getSessionOptionsMaterialPage(state),
),
GoRoute(
path: 'folder/:fid',
routes: [
GoRoute(
path: 'folder2/:f2id',
routes: [
GoRoute(
path: 'folder3/:f3id',
pageBuilder: (context, state) => getFolderMaterialPage(state),
),
],
pageBuilder: (context, state) =>
getFolderMaterialPage(state),
),
],
pageBuilder: (context, state) => getFolderMaterialPage(state), …Run Code Online (Sandbox Code Playgroud) 我正在使用go_router构建一个执行“虚拟”路由推送的应用程序(有点像 Twitter)。可以从一个页面开始/a,推送/b,然后/c,...然后再次推送/a。
当页面被推送两次时,会assert失败:assert(!keyReservation.contains(key));这确保了密钥在Navigator.
有没有办法能够使用 go_router 推送两次同一页面?
这是一个小代码片段:
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
void main() {
runApp(const MyApp());
}
final router = GoRouter(
initialLocation: '/a',
routes: [
GoRoute(
path: '/a',
builder: (_, __) => const MyWidget(path: '/a'),
),
GoRoute(
path: '/b',
builder: (_, __) => const MyWidget(path: '/b'),
),
],
);
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is …Run Code Online (Sandbox Code Playgroud)