我正在制作一个包含4个不同页面的项目。我使用“ BottomNavigationBar”小部件导航到每个页面。当按下“ BottomNavigationBar”中的图标时,我在支架体内显示了不同的页面。我不使用任何路由,因此当用户在Android上按下时,该应用程序将关闭。我不想发生的事情。
我找到的所有指南在导航时都会重新加载整个“ Scaffold”,但是我只想更新“ Scaffold”小部件的“ body”属性。当发生Navigation.pop()
时,我再次只希望更改“脚手架”正文。
我在同一问题上发现了a post,但是答案对我来说不起作用。
我可以尝试的另一种解决方法是制作一个自定义历史记录列表,然后在页面更改时更新该列表。按下后退按钮时,捕获OnWillPop事件以更新页面。我没有尝试过,因为我觉得必须有更好的方法。
显示页面的脚手架小部件。
Widget createScaffold() {
return Scaffold(
backgroundColor: Colors.white,
appBar: EmptyAppBar(),
body: _displayedPage,
bottomNavigationBar: createBottomNavigationbar(),
);
}
BottomNavigationBar小部件。
Widget createBottomNavigationbar() {
return BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: _selectedIndex,
onTap: _onItemTapped,
items: [
BottomNavigationBarItem(
icon: new Icon(Icons.home,
color: _selectedIndex == 0 ? selectedColor : unselectedColor),
title: new Text('Home',
style: new TextStyle(
color:
_selectedIndex == 0 ? selectedColor : unselectedColor)),
),
BottomNavigationBarItem(
icon: new Icon(Icons.show_chart,
color: _selectedIndex == 1 ? selectedColor : unselectedColor),
title: new Text('Month',
style: new TextStyle(
color:
_selectedIndex == 1 ? selectedColor : unselectedColor)),
),
BottomNavigationBarItem(
icon: Icon(Icons.history,
color: _selectedIndex == 2 ? selectedColor : unselectedColor),
title: Text('History',
style: new TextStyle(
color: _selectedIndex == 2
? selectedColor
: unselectedColor))),
BottomNavigationBarItem(
icon: Icon(Icons.settings,
color: _selectedIndex == 3 ? selectedColor : unselectedColor),
title: Text('Settings',
style: new TextStyle(
color: _selectedIndex == 3
? selectedColor
: unselectedColor)))
],
);
}
更新显示页面状态的方法。
void _onItemTapped(int index) {
_changeDisplayedScreen(index);
setState(() {
_selectedIndex = index;
});
}
void _changeDisplayedScreen(int index) {
switch (index) {
case 0:
setState(() {
_displayedPage = new LatestReadingPage();
});
break;
case 1:
setState(() {
_displayedPage = new HomeScreen();
//Placeholder
});
break;
case 2:
setState(() {
_displayedPage = new HomeScreen();
//Placeholder
});
break;
case 3:
setState(() {
_displayedPage = new HomeScreen();
//Placeholder
});
break;
default:
setState(() {
_displayedPage = new LatestReadingPage();
});
break;
}
}
}
我想要的是能够使用Flutter Navigation基础结构,但仅在更改页面时更新Scaffold小部件的body属性。而不是整个屏幕。
非常类似于Youtube应用或Google新闻应用。
答案 0 :(得分:0)
您尝试过吗?
return Scaffold(
backgroundColor: Colors.white,
appBar: EmptyAppBar(),
body: _displayedPage[_selectedIndex],
bottomNavigationBar: _createBottomNavigationbar,
);
然后,创建所需的所有屏幕的窗口小部件列表:
List<Widget> _displayedPage = [LatestReadingPage(), HomeScreen(), ExampleScreen()];
答案 1 :(得分:0)
我已为您链接的帖子添加了答案:https://stackoverflow.com/a/59133502/6064621
下面的答案与上面的答案相似,但我还在此处添加了未知的路线:
您可以通过使用自定义Navigator来实现。
Flutter团队对此做了video,他们关注的文章在这里:https://medium.com/flutter/getting-to-the-bottom-of-navigation-in-flutter-b3e440b9386
基本上,您需要将脚手架的主体包装在自定义Navigator
中:
class _MainScreenState extends State<MainScreen> {
final _navigatorKey = GlobalKey<NavigatorState>();
// ...
@override
Widget build(BuildContext context) {
return Scaffold(
body: Navigator(
key: _navigatorKey,
initialRoute: '/',
onGenerateRoute: (RouteSettings settings) {
WidgetBuilder builder;
// Manage your route names here
switch (settings.name) {
case '/':
builder = (BuildContext context) => HomePage();
break;
case '/page1':
builder = (BuildContext context) => Page1();
break;
case '/page2':
builder = (BuildContext context) => Page2();
break;
default:
throw Exception('Invalid route: ${settings.name}');
}
// You can also return a PageRouteBuilder and
// define custom transitions between pages
return MaterialPageRoute(
builder: builder,
settings: settings,
);
},
),
bottomNavigationBar: _yourBottomNavigationBar,
);
}
}
在底部导航栏中,要导航到新的自定义Navigator
中的新屏幕,只需调用以下名称:
_navigatorKey.currentState.pushNamed('/yourRouteName');
如果您不使用命名路线,那么您应该针对自定义Navigator
以及导航到新屏幕执行以下操作:
// Replace the above onGenerateRoute function with this one
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute(
builder: (BuildContext context) => YourHomePage(),
settings: settings,
);
},
_navigatorKey.currentState.push(MaterialPageRoute(
builder: (BuildContext context) => YourNextPage(),
));
要让Navigator.pop
带您到上一个视图,您将需要用Navigator
包装自定义WillPopScope
:
@override
Widget build(BuildContext context) {
return Scaffold(
body: WillPopScope(
onWillPop: () async {
if (_navigatorKey.currentState.canPop()) {
_navigatorKey.currentState.pop();
return false;
}
return true;
},
child: Navigator(
// ...
),
),
bottomNavigationBar: _yourBottomNavigationBar,
);
}
就应该这样!无需过多地手动处理弹出窗口或管理自定义历史记录列表。
答案 2 :(得分:0)
将您的身体包裹在IndexedStack小部件中。像这样:
body: IndexedStack(
index: selectedIndex,
children: _children, //define a widget children list
),
这里是链接https://medium.com/flutter/getting-to-the-bottom-of-navigation-in-flutter-b3e440b9386