Is it possible to pass AppBar from body in Scaffold widget?

喜夏-厌秋 提交于 2020-01-03 06:35:31

问题


I have a Scaffold widget with drawer. The screens I need to show in body have different AppBars (some of them have indicators for PageView, some of them are single paged, some have logo in it). So I do not pass any AppBar to my Scaffold but include it in widget I use in body. But there is no hamburger icon for drawer and it.

Is it possible to pass this AppBar from my body widget to the Scaffold containing it?

Or if there is a better way of widgets composition to solve this scenario I'd like to give it a try.

UPD

There is a nice way to show BottomSheet os SnackBar with

Scaffold.of(context)
    .showSnackBar(SnackBar(content: Text('Processing Data')));

Unfortunately it is not the case for AppBar.


回答1:


It seems like you want a global Scaffold that stays the same when you switch pages. In that case you have to write your own logic to make the menu button appear:

import 'package:flutter/material.dart';

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

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      builder: (context, child) {
        // wrap a scaffold around the Navigator so that it is the same for all pages
        return Scaffold(
          body: AppScaffold(child: child),
          drawer: Drawer(),
        );
      },
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: buildLeadingAction(context),
        title: Text('Home'),
      ),
    );
  }
}

/// Makes it easier to access the outer scaffold with the drawer from any context
class AppScaffold extends InheritedWidget {
  const AppScaffold({Key key, @required Widget child})
      : assert(child != null),
        super(key: key, child: child);

  /// nullable
  static ScaffoldState of(BuildContext context) {
    return context
        .ancestorInheritedElementForWidgetOfExactType(AppScaffold)
        ?.ancestorStateOfType(const TypeMatcher<ScaffoldState>());
  }

  @override
  bool updateShouldNotify(AppScaffold old) => false;
}

/// This is a simple method and not a widget
/// so that null can be returned if no AppScaffold with a drawer was found
Widget buildLeadingAction(BuildContext context) {
  final ScaffoldState appScaffold = AppScaffold.of(context);
  if (appScaffold != null && appScaffold.hasDrawer) {
    return IconButton(
      icon: const Icon(Icons.menu),
      onPressed: () => appScaffold.openDrawer(),
      tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
    );
  } else {
    return null;
  }
}

Alternatively you can also place the Scaffold for the drawer inside of the page, and use a GlobalKey to access its ScaffoldState.



来源:https://stackoverflow.com/questions/53957287/is-it-possible-to-pass-appbar-from-body-in-scaffold-widget

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