【问题标题】:Flutter Web Navigation with persistent drawer and appbar带有持久抽屉和应用栏的 Flutter Web Navigation
【发布时间】:2020-09-03 02:37:48
【问题描述】:

我的 Flutter Web 应用程序仍然没有成功,执行基于 URL 的路由并保持 appbar 和抽屉等内容持久。

我想要实现的目标是,我只能修改我的应用程序的内容。因此,即如果用户输入 url $baseurl/#/ 它应该导航到第一页的内容。 $baseurl/#/two 到第二页的内容,以此类推...

我的主文件是这样的。如您所见,它是使用 Fluro Router 完成的,我尝试简化所有内容以查看我的主要目标。

import 'package:flutter/material.dart';
import 'package:newnavigationtest/routes.dart';

void main() {
  FluroRouter.setupRouter();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  final navigatorKey = GlobalKey<NavigatorState>();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: MainLayout(),
    );
  }
}

class MainLayout extends StatelessWidget {
  final navigatorKey = GlobalKey<NavigatorState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Row(
        children: <Widget>[
          Column(
            children: [
              Expanded(
                child: Container(
                  color: Colors.green,
                  width: 100,
                  child: Text("Static sidebar"),
                ),
              ),
            ],
          ),
          Expanded(
            child: Navigator(
              key: navigatorKey,
              initialRoute: '/',
              onGenerateRoute: FluroRouter.router.generator,
            ),
          )
        ],
      ),
    );
  }
}

FluroRouter 文件如下所示

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

class FluroRouter {
  static Router router = Router();
  static Handler _routeOneHandler = Handler(
      handlerFunc: (BuildContext context, Map<String, dynamic> params) =>
          Container(child: Center(child: Text("Later content for page 1"))));
  static Handler _routeTwoHandler = Handler(
      handlerFunc: (BuildContext context, Map<String, dynamic> params) =>
          Container(child: Center(child: Text("Later content for page 2"))));
  static void setupRouter() {
    router.define(
      '/',
      handler: _routeOneHandler,
    );
    router.define(
      '/two',
      handler: _routeTwoHandler,
    );
  }
}

很明显,如果用户输入一个 URL,此时什么都不会发生。我认为这是因为 MaterialApp 中的主导航器正在消耗用户的输入,而不是将其传递给我在脚手架中的导航器。但我完全不确定。

谁能指出我实现所需行为的正确方法?

谢谢!

更新 1:

我还尝试过使用构建器来构建孩子并保持其余部分持久化。 (这导致我正在寻找我正在寻找的行为,除了 OverLay 错误)

import 'package:flutter/material.dart';
import 'package:newnavigationtest/routes.dart';

void main() {
  FluroRouter.setupRouter();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  final navigatorKey = GlobalKey<NavigatorState>();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      key: navigatorKey,
      initialRoute: '/',
      onGenerateRoute: FluroRouter.router.generator,
      builder: (context, child) {
        return MainLayout(child: child);
      },
    );
  }
}

class MainLayout extends StatelessWidget {
  final Widget child;

  MainLayout({@required this.child});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Row(
        children: <Widget>[
          Column(
            children: [
              Expanded(
                child: Container(
                  color: Colors.green,
                  width: 100,
                  child:
                      Tooltip(message: "Hello", child: Text("Static sidebar")),
                ),
              ),
            ],
          ),
          Expanded(
            child: child,
          )
        ],
      ),
    );
  }
}

但这会导致工具提示处缺少叠加层。

════════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown building Tooltip("Hello", dirty, state: _TooltipState#93c0f(ticker inactive)):
No Overlay widget found.

Tooltip widgets require an Overlay widget ancestor for correct operation.

【问题讨论】:

  • 你可以试试flutter自动路由,这很容易实现,在文档中:pub.dev/packages/auto_route#nested-routes
  • 我猜使用scaffoldKey 或scaffold.of() 可能有效。 ???但我知道怎么做。

标签: flutter flutter-web flutter-navigation


【解决方案1】:

因为Fluro 重定向没有持久性,您可能必须让每个页面都有一个带有 AppBar 和 Drawer 的 Scaffold,最有效的方法是拥有一个可以重复使用的自定义脚手架。

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

void main() {
  FluroRouter.setupRouter();
  runApp(
    MaterialApp(
      title: 'Your website',
      onGenerateRoute: FluroRouter.router.generator
    ),
  );
}

class CustomScaffold extends StatelessWidget {
  final Widget body;
  CustomScaffold({this.body});
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      //your appbar here
      appBar: AppBar(),
      //your drawer here
      drawer: Drawer(),
      body: body,
    );
  }
}

class FluroRouter {
  static Router router = Router();
  static Handler _routeOneHandler = Handler(
      handlerFunc: (BuildContext context, Map<String, dynamic> params) => PageOne());
  static Handler _routeTwoHandler = Handler(
      handlerFunc: (BuildContext context, Map<String, dynamic> params) => PageTwo());
  static void setupRouter() {
    router.define(
      '/',
      handler: _routeOneHandler,
    );
    router.define(
      '/two',
      handler: _routeTwoHandler,
    );
  }
}

class PageOne extends StatelessWidget {
  Widget build(BuildContext context) {
    return CustomScaffold(
      body: Container(child: Text('Page 1')),
    );
  }
}

class PageTwo extends StatelessWidget {
  Widget build(BuildContext context) {
    return CustomScaffold(
      body: Container(child: Text('Page 2')),
    );
  }
}

【讨论】:

  • 谢谢!这已经很好地解决了这个问题,但这也将在每次页面切换时重建整个脚手架。所以我需要一个选项,其中身体被注入而不是使用返回的 CustomScaffold 构建。还有什么想法吗?谢谢! :)
  • 您可以使用选项卡视图,但不能将 URL 定向到依赖小部件 - 仅限页面
  • 您可以将a指向具有不同参数的Scaffold以显示不同的内容,问题是正在路由的url,这意味着它正在加载一个新的“页面”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多