是否可以从Scaffold小部件中的主体传递AppBar? [英] Is it possible to pass AppBar from body in Scaffold widget?
问题描述
我有一个带有drawer
的Scaffold
小部件.我需要在body
中显示的屏幕具有不同的AppBars
(其中一些具有PageView
的指示符,其中一些是单页的,某些中具有徽标).
因此,我没有将任何AppBar
传递给我的Scaffold
,而是将其包含在我在body
中使用的小部件中.但是抽屉里没有汉堡图标.
是否可以将此AppBar
从我的body
小部件传递到包含它的Scaffold
?
或者,如果有一种更好的小部件组合方式来解决这种情况,我想尝试一下.
UPD
有一种很好的方式来显示
的BottomSheet
操作系统SnackBar
Scaffold.of(context)
.showSnackBar(SnackBar(content: Text('Processing Data')));
不幸的是,AppBar
并非如此.
似乎您希望全局Scaffold
在切换页面时保持不变.在这种情况下,您必须编写自己的逻辑以使菜单按钮出现:
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;
}
}
或者,您也可以将抽屉的Scaffold
放置在页面的内部,并使用GlobalKey
来访问其ScaffoldState
.
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
.
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
.
这篇关于是否可以从Scaffold小部件中的主体传递AppBar?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!