我想在所有屏幕上保留 Navigation Drawer。对此有很多问题,但我的问题与例如Persisting AppBar Drawer across all Pages Flutter
我有抽屉导航,其中包含名为 A、B 和 C 的项目列表。在抽屉导航中单击 A 时,屏幕 A 打开,B 和 C 分别打开相同的内容。现在 C 屏幕有一个按钮,单击该按钮按钮 我要去屏幕 D,现在虽然屏幕 D 显示抽屉导航图标,但抽屉永远不会打开。我尝试在调用抽屉的方法中打印一条语句,打印语句确实打印但抽屉永远不会打开。以下是我的代码
我有一个基类,它的抽屉如下
class BaseScreen extends StatefulWidget {
final List<Menu> menuList;
final String userType;
final String userId;
const BaseScreen({Key key, this.menuList, this.userType, this.userId})
: super(key: key);
@override
BaseScreenState createState() {
return new BaseScreenState();
}
}
class BaseScreenState extends State<BaseScreen> {
String screenNameSelected = "A";
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
_getDrawerItemWidget(screenNameSelected),
],
),
drawer: SizedBox(
width: 100,
child: Drawer(
child: ListView.separated(
separatorBuilder: (context, index) => Material(
elevation: 2,
shadowColor: shadow,
child: Divider(
color: white,
),
),
itemBuilder: (BuildContext context, int index) {
return ListTile(
onTap: () {
openScreen(
widget.menuList[index].title,
widget.userId,
MenuList.returnLoginType(widget.userType).toString(),
context);
Navigator.pop(context);
},
title: Padding(
padding: const EdgeInsets.only(top: 8),
child: Image.asset(
widget.menuList[index].image,
width: 35,
height: 35,
),
),
);
},
itemCount: widget.menuList?.length ?? 0,
shrinkWrap: true,
physics: BouncingScrollPhysics(),
),
),
),
);
}
_getDrawerItemWidget(String selectedScreenName) {
switch (selectedScreenName) {
case A:
return A();
case B:
return B();
case C:
return C();
default:
return Container();
}
}
void openScreen(String screenName, String userId, String loginType,
BuildContext context) {
if (screenName.toLowerCase() == "A".toLowerCase()) {
setState(() {
screenNameSelected = "A";
});
} else if (screenName.toLowerCase() == "B".toLowerCase()) {
setState(() {
screenNameSelected = "B";
});
} else if (screenName.toLowerCase() == "C".toLowerCase()) {
setState(() {
screenNameSelected = "C";
});
}
}
}
我已经为应用栏创建了一个自定义类,因为我的应用栏是高度定制的
class CustomAppBar extends StatelessWidget {
final String subTitleText;
final String subTitleImage;
const CustomAppBar(
{Key key, @required this.subTitleText, @required this.subTitleImage})
: super(key: key);
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
SafeArea(
child: Column(
children: <Widget>[
Builder(builder: (context) => customAppBar(context)),
SizedBox(
height: 5.0,
),
subTitleRow(
subTitleText,
subTitleImage,
)
],
),
),
],
);
}
}
Widget subTitleRow(String subtitleText, String subtitleImage) {
.........
}
Widget customAppBar(BuildContext context) {
return Material(
elevation: 5.0,
shadowColor: shadow,
child: SafeArea(
child: Stack(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Image.asset(
"images/toolbar_logo.webp",
width: 80,
height: 50,
),
],
),
IconButton(
icon: Image.asset("images/menu.webp"),
onPressed: () {
Scaffold.of(context).openDrawer();
},
iconSize: 20,
),
],
),
),
);
}
现在我的 A、B 和 C 类没有脚手架,但我为 D 类提供了脚手架,我认为这是导致问题的原因。不为 D 类提供脚手架不会提供正确的布局
A、B、C类代码如下
class A extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ShortBioProvider(
child: Column(
children: <Widget>[
CustomAppBar(
subTitleImage: "images/settings.webp",
subTitleText: SETTINGS.toUpperCase(),
),
SizedBox(
height: 20,
),
SettingsList(),
],
),
);
}
}
B 和 C 与 A 非常相似。
现在是D类代码
class D extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(body: Column(children: <Widget>[
CustomAppBar(
subTitleImage: "images/settings.webp",
subTitleText: D.toUpperCase(),
),
SizedBox(
height: 20,
),
........
],),);
}
}
我对上面的类进行了很多编辑,所以这里或那里可能缺少括号或分号
最佳答案
啊,现在您已经添加了您的代码,这很有意义。
发生的事情是,在 D 的情况下,您有两个不同的脚手架:
BaseScreenState
--> Scaffold 1
--> drawer
body
--> stack
--> D
--> Scaffold 2
-->CustomAppBar ....
当您执行 Scaffold.of(context) 时,它会向上查找树以找到最近的脚手架,在本例中恰好是没有抽屉的脚手架 2。你的 D 类中的脚手架似乎没有做任何事情,所以删除它应该可以解决你的问题。
然而
您的代码中存在一些更严重的问题。您几乎不应该使用堆栈在页面之间切换。一方面,flutter 无法以这种方式缓存小部件,但它也消除了屏幕转换等内容。
您应该做的是为应用中的每个页面创建一个包含脚手架、抽屉、应用栏等的页面,然后使用导航器在这些页面之间切换。 (请注意,仅仅因为您为每个页面制作了一个小部件,并不意味着组件不能共享)。
一个在flutter中有意义的架构如下:
onGenerateRoute - 我发现这可以比动态构建更清晰、更容易地判断正在发生的事情。 还有一些需要注意的事情是:
希望对您有所帮助!
关于dart - 抽屉导航不适用于屏幕内的屏幕,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54540486/
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm
当我使用has_one时,它工作得很好,但在has_many上却不行。在这里您可以看到object_id不同,因为它运行了另一个SQL来再次获取它。ruby-1.9.2-p290:001>e=Employee.create(name:'rafael',active:false)ruby-1.9.2-p290:002>b=Badge.create(number:1,employee:e)ruby-1.9.2-p290:003>a=Address.create(street:"123MarketSt",city:"SanDiego",employee:e)ruby-1.9.2-p290
相信很多人在录制视频的时候都会遇到各种各样的问题,比如录制的视频没有声音。屏幕录制为什么没声音?今天小编就和大家分享一下如何录制音画同步视频的具体操作方法。如果你有录制的视频没有声音,你可以试试这个方法。 一、检查是否打开电脑系统声音相信很多小伙伴在录制视频后会发现录制的视频没有声音,屏幕录制为什么没声音?如果当时没有打开音频录制,则录制好的视频是没有声音的。因此,建议在录制前进行检查。屏幕上没有声音,很可能是因为你的电脑系统的声音被禁止了。您只需打开电脑系统的声音,即可录制音频和图画同步视频。操作方法:步骤1:点击电脑屏幕右下侧的“小喇叭”图案,在上方的选项中,选择“声音”。 步骤2:在“声
我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty
我正在使用带有Rails的Devise,我想添加一个方法“getAllComments”,所以我这样写:classUser在我的Controller中:defdashboard@user=current_user@comments=@user.getAllComments();end当我访问我的url时,我得到了undefinedmethod`getAllComments'for#我做错了什么?谢谢 最佳答案 因为getAllComments是一个类方法,而您正试图将其作为实例方法访问。您要么需要访问它:User.getAllCom
我正在使用Rails3.2.3和Ruby1.9.3p0。我发现我经常需要确定某个字符串是否出现在选项列表中。看来我可以使用Ruby数组.includemethod:或正则表达式equals-tildematchshorthand用竖线分隔选项:就性能而言,一个比另一个好吗?还有更好的方法吗? 最佳答案 总结:Array#include?包含String元素,在接受和拒绝输入时均胜出,对于您的示例只有三个可接受的值。对于要检查的更大的集合,看起来Set#include?和String元素可能会获胜。如何测试我们应该根据经验对此进行测试
我正在尝试提取方括号内的内容。到目前为止,我一直在使用它,它有效,但我想知道我是否可以直接在正则表达式中使用某些东西,而不是使用这个删除功能。a="Thisissuchagreatday[coolawesome]"a[/\[.*?\]/].delete('[]')#=>"coolawesome" 最佳答案 差不多。a="Thisissuchagreatday[coolawesome]"a[/\[(.*?)\]/,1]#=>"coolawesome"a[/(?"coolawesome"第一个依赖于提取组而不是完全匹配;第二个利用前瞻和
Ruby初学者努力简单地将这个@@people散列的值打印到控制台classPerson#haveafirst_nameandlast_nameattributewithpublicaccessorsattr_accessor:first_nameattr_accessor:last_name#haveaclassattributecalled`people`thatholdsanarrayofobjects@@people=[]#havean`initialize`methodtoinitializeeachinstancedefinitialize(first_name,last_
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:AmazonAPIlibraryforPython?我正在寻找一个AmazonAPI,它可以让我:按书名或作者查找书籍显示书籍封面获取有关每本书的信息(价格、评级、评论数、格式、页数等)Python或Ruby库都可以(我只想要最容易使用的库)。有什么建议么?我知道在SO上还有其他一些关于此的帖子,但这些API似乎很快就过时了。[几个月前我尝试了几个建议的Ruby库,但无法让它们中的任何一个工作。]