Making fixed app-wide menu instead of Drawer on tablets in Flutter

一个人想着一个人 提交于 2020-12-12 07:19:13

问题


My application has a lot of routes and almost every route uses Scaffold with the same Drawer menu to navigate inside the app (my own CustomDrawer widget). As for devices with big screen, I want to always show the menu on the left side in layout, instead of using Drawer (it works like this in Gmail app. I attached a pic). In other words, I need to make a responsive layout with fixed menu.

What I've tried:

  • I know that you can use LayoutBuilder to learn constraints size;
  • Making same layout inside every route will work, but it's bad solution because each route will build menu for itself (scroll position will be different, there will be many states for many menus etc.). I need one app-wide menu for many different routes, but it's impossible to make layout on top routes;
  • Squashing all routes into one route with changing state of main content will take a lot of refactoring and doesn't sound good at all.

In React the app layout would look something like this:

    <App>
      <Menu />
      <main className="content">
        <Switch>
          <Route path="/about" component={About} />
          <Route path="/contact" component={Contact} />
          <Route path="/" component={Home} />
        </Switch>
      </main>
    </App>

But I have no idea how to make something like this in Flutter.

tl;dr: To make UI responsive for big screens, I want to show fixed menu instead of Drawer. One menu for whole app, not for every route.


回答1:


The trick was to use a nested navigator. If viewport's width is big, I put a menu in a row with content, otherwise pass a menu to Scaffold as drawer parameter.

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final String title;

  MyHomePage({Key key, this.title}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final routes = List.generate(20, (i) => 'test $i');

  final navigatorKey = GlobalKey<NavigatorState>();

  bool isMenuFixed(BuildContext context) {
    return MediaQuery.of(context).size.width > 500;
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);

    final menu = Container(
      color: theme.canvasColor,
      child: SafeArea(
        right: false,
        child: Drawer(
          elevation: 0,
          child: ListView(
            children: <Widget>[
              for (final s in routes)
                ListTile(
                  title: Text(s),
                  onTap: () {
                    // Using navigator key, because the widget is above nested navigator  
                    navigatorKey.currentState.pushNamedAndRemoveUntil(s, (r) => false);

                    // navigatorKey.currentState.pushNamed(s);
                  },
                ),
            ],
          ),
        )
      )
    );

    return Row(
      children: <Widget>[
        if (isMenuFixed(context))
          menu,
        Expanded(
          child: Navigator(
            key: navigatorKey,
            initialRoute: '/',
            onGenerateRoute: (settings) {
              return MaterialPageRoute(
                builder: (context) {
                  return Scaffold(
                    appBar: AppBar(
                      title: Text(settings.name),
                    ),
                    body: SafeArea(
                      child: Text(settings.name),
                    ),
                    drawer: isMenuFixed(context) ? null : menu,
                  );
                },
                settings: settings
              );
            },
          ),
        ),
      ],
    );
  }
}


来源:https://stackoverflow.com/questions/58877550/making-fixed-app-wide-menu-instead-of-drawer-on-tablets-in-flutter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!