如何使用底部导航栏从脚手架主体内部推送路线?
Posted
技术标签:
【中文标题】如何使用底部导航栏从脚手架主体内部推送路线?【英文标题】:How to push a Route from inside the body of a scaffold with a bottomnavigationbar? 【发布时间】:2021-09-22 07:51:23 【问题描述】:我的 main.dart 在 Nav() 小部件内有一个 MaterialApp,它包含一个带有 appBar 和 BottomNavigationBar 的 Scaffold。 NavigationBar 有 4 个 BottomNavigationBarItems,但我的整个应用程序中的页面数超过了 4 个。其他页面可以通过第一个 BottomNavigationBarItem 'Home' 访问。但是当我推送新的 NamedRoute 时,AppBar 消失了。我该如何解决这个问题?
我已经尝试在我自己的小部件中的新文件中使用底部导航栏。问题:setState() 不起作用。
这里有一些代码
main.dart:
import 'package:flutter/material.dart';
import 'pages/nav.dart';
import 'route/route.dart' as route;
void main()
runApp(MyApp());
class MyApp extends StatelessWidget
// This widget is the root of your application.
@override
Widget build(BuildContext context)
return MaterialApp(
title: 'Lieferantenapp',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.red,
),
home: Nav(),
onGenerateRoute: route.controller,
//initialRoute: route.navPage,
);
nav.dart
import 'package:flutter/material.dart';
import 'package:lieferantenapp/components/MyAppBar.dart';
import 'package:lieferantenapp/components/MyThreeLineText.dart';
//import 'package:lieferantenapp/components/myBottomNavigationBar.dart';
import 'package:lieferantenapp/components/myCard.dart';
import 'package:lieferantenapp/pages/bestellungen.dart';
import 'package:lieferantenapp/pages/packliste.dart';
import 'package:lieferantenapp/pages/tour.dart';
import 'package:lieferantenapp/pages/home.dart';
class Nav extends StatefulWidget
@override
_NavState createState() => _NavState();
class _NavState extends State<Nav>
int _selectedIndex = 0;
List<Widget> _widgetOptions = <Widget>[
Home(),
Tour(),
Bestellungen(),
Packliste(),
];
void _onItemTap(int index)
setState(()
_selectedIndex = index;
);
@override
Widget build(BuildContext context)
return Scaffold(
//Custom App Bar without any passed data
appBar: myAppBar(context, null, null),
backgroundColor: Colors.white,
bottomNavigationBar: BottomNavigationBar(
currentIndex: _selectedIndex,
type: BottomNavigationBarType.fixed,
fixedColor: Colors.red,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
BottomNavigationBarItem(
icon: Icon(Icons.local_shipping),
label: 'Tour',
),
BottomNavigationBarItem(
icon: Icon(Icons.inventory_2),
label: 'Packliste',
),
BottomNavigationBarItem(
icon: Icon(Icons.receipt_long),
label: 'Bestellungen',
),
],
onTap: _onItemTap,
),
body: _widgetOptions.elementAt(_selectedIndex),
);
home.dart:
import 'package:flutter/material.dart';
import 'package:lieferantenapp/components/MyThreeLineText.dart';
import 'package:lieferantenapp/components/myCard.dart';
class Home extends StatelessWidget
@override
Widget build(BuildContext context)
return Column(
children: [
//BlackBoard Message
//TODO get BlackBoard Message from Server
//myThreeLineText(Context, TextTheme, OVerline, Title, Body)
myThreeLineText(
context,
Theme.of(context).textTheme,
'12.07.2021',
'Servus und Mahlzeit!',
"Herzlich Willkommen in der neuen Mahlzeit LieferApp mit " +
"optimierter Routenplanung via Google Maps.",
),
Expanded(
child: GridView.count(
shrinkWrap: true,
primary: false,
padding: const EdgeInsets.all(18),
crossAxisSpacing: 15,
mainAxisSpacing: 15,
crossAxisCount: 2,
children: <Widget>[
myCard(
context,
Icons.map_outlined,
'Touren',
Theme.of(context).textTheme,
Color(0xff119052),
),
myCard(
context,
Icons.local_shipping_outlined,
'Touren',
Theme.of(context).textTheme,
Color(0xffFF9444),
),
myCard(
context,
Icons.inventory_2_outlined,
'Touren',
Theme.of(context).textTheme,
Color(0xff84000F),
),
myCard(
context,
Icons.receipt_long_outlined,
'Touren',
Theme.of(context).textTheme,
Color(0xffCB5E5E),
),
myCard(
context,
Icons.bookmark_border_outlined,
'Touren',
Theme.of(context).textTheme,
Color(0xffCC3021),
),
myCard(
context,
Icons.settings_outlined,
'Touren',
Theme.of(context).textTheme,
Color(0xff57BB61),
),
],
),
),
],
);
myCard.dart:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:lieferantenapp/route/route.dart' as route;
Widget myCard(BuildContext context, IconData icon, String text, TextTheme theme,
Color cColor)
return GestureDetector(
//TODO implement ROUTE ontap start Cards
onTap: () => ,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
icon,
color: Colors.white,
size: 30,
),
SizedBox(height: 25),
Text(
text,
style: theme.bodyText1.apply(color: Colors.white),
),
],
),
color: cColor,
),
);
我也愿意接受提示和技巧来改进我的代码。
编辑 - 新 main.dart:
import 'package:flutter/material.dart';
import 'package:lieferantenapp/components/MyAppBar.dart';
import 'pages/nav.dart';
import 'route/route.dart' as route;
void main()
runApp(MyApp());
class MyApp extends StatelessWidget
// This widget is the root of your application.
@override
Widget build(BuildContext context)
return MaterialApp(
title: 'Mahlzeit Lieferantenapp',
theme: ThemeData(
primarySwatch: Colors.red,
),
//home: Nav(),
//onGenerateRoute: route.controller,
builder: (context, _) => Scaffold(
appBar: myAppBar(context, null, null),
body: Navigator(onGenerateRoute: route.controller),
),
//initialRoute: route.navPage,
);
【问题讨论】:
【参考方案1】:应用栏是 Scaffold 的一部分,它只会出现在 _widgetOptions 中的 4 个小部件上。如果您的页面上没有该 Scaffold,则没有应用栏。
用脚手架(即导航器顶部的脚手架)包裹导航器应该可以解决问题。
请注意,当您从构建函数“返回”一个小部件时,它会变成一个子部件。当您使用 Navigator 推送一个 Widget 时,它会成为一个兄弟,并将位于当前屏幕的顶部。您可以在开发工具中清楚地看到这一点。
编辑:由于您使用的是默认 MaterialApp 的导航器,这将不起作用。您需要为此创建自己的导航器。
即:从 MaterialApp 中删除 home 参数。请改用 builder 参数。并为构建器提供一个 Navigator 小部件(由您的 Scaffold 包装)
类似这样的:
MaterialApp(builder: (context, _) => Scaffold(....., body: Navigator(onGenerateRoutes:...)))
【讨论】:
感谢您的快速回答!我收到上面发布的新 main.dart 的以下错误:A HeroController can not be shared by multiple Navigators. The Navigators that share the same HeroController are:
错误在“是:”之后结束 编辑:忘记了初始路由 - 修复了错误
收到另一个错误:The following _CompileTimeError was thrown building Builder(dirty): Unimplemented handling of missing static target The relevant error-causing widget was MaterialApp
你知道如何解决吗?或者你知道另一种解决方法吗?
我相信热重启或停止并重新运行应用程序应该可以修复该错误。
如果我的回答有帮助,请接受并点赞以上是关于如何使用底部导航栏从脚手架主体内部推送路线?的主要内容,如果未能解决你的问题,请参考以下文章