如何在 Flutter 的底部导航中处理后退导航
Posted
技术标签:
【中文标题】如何在 Flutter 的底部导航中处理后退导航【英文标题】:How to handle back navigation in Bottom Navigation in Flutter 【发布时间】:2020-12-17 22:32:15 【问题描述】:我正在制作一个颤振应用程序,其中流程是这样的:启动画面,它将检查用户是否登录。如果未登录,则转到登录屏幕,否则转到主屏幕。主屏幕具有三个选项卡的底部导航,每个选项卡都有自己的导航器,在每个导航器中,某些屏幕可能不会显示底部栏。所以我一直编码到现在。
class MyApp extends StatelessWidget
@override
Widget build(BuildContext context)
return MaterialApp(
title: 'Flutter',
home: Splash(),
routes: <String, WidgetBuilder>
'/main_tab': (context) => new MainScreen(),
'/login': (context) => new Login(),
,
);
现在有底部标签的 MainScreen 是这样的。
class MainScreen extends StatefulWidget
@override
_MainScreenState createState() => new _MainScreenState();
class _MainScreenState extends State<MainScreen>
final _navigatorKey = GlobalKey<NavigatorState>();
int _selectedIndex = 0;
int _lastIndex = 0;
void _onItemTapped(int index)
if(index == 0) _navigatorKey.currentState.pushNamed('/');
else if(index == 1) _navigatorKey.currentState.pushNamed('/page1');
else if(index == 2) _navigatorKey.currentState.pushNamed('/page2');
setState(()
_lastIndex = _selectedIndex;
_selectedIndex = index;
);
@override
Widget build(BuildContext context)
return Scaffold(
body: WillPopScope(
onWillPop: () async
if(_selectedIndex == 0) SystemNavigator.pop();
else if (_navigatorKey.currentState.canPop())
_navigatorKey.currentState.pop();
setState(()
_selectedIndex = _lastIndex;
// _lastIndex = _selectedIndex;
);
return false;
return true;
,
child: Navigator(
key: _navigatorKey,
initialRoute: '/',
onGenerateRoute: (RouteSettings settings)
WidgetBuilder builder;
// Manage your route names here
switch (settings.name)
case '/':
builder = (BuildContext context) => Page1();
break;
case '/page1':
builder = (BuildContext context) => Page2();
break;
case '/page2':
builder = (BuildContext context) => Page3();
break;
default:
throw Exception('Invalid route: $settings.name');
return MaterialPageRoute(
builder: builder,
settings: settings,
);
),
),
bottomNavigationBar:BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
title: Text('Business'),
),
BottomNavigationBarItem(
icon: Icon(Icons.school),
title: Text('School'),
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
type: BottomNavigationBarType.fixed,
),
);
根据我的要求,一切正常。要导航到没有底栏的屏幕,我遇到了一些问题,但我通过使用rootnavigator:true
并在MainApp()
中声明该路线来管理它。
现在,担心的是,当我按下返回按钮时,屏幕弹出工作正常,但它并没有改变底部栏选择的索引。所以我把逻辑放在 willPop 中,但那不能正常工作。
所以请告诉我如何处理底部栏中的后按,并且它应该更改底部栏的选定选项卡。
【问题讨论】:
【参考方案1】:在我参与的一个项目中,我必须这样做。应用程序有底部导航,一些页面正在使用根导航器推送。为了处理后退动作,我这样做了:
WillPopScope(
onWillPop: () async
bool canPop = await appFlows[currentTabIndex]
.navigatorKey
.currentState
.maybePop();
if (canPop)
return false;
if (currentTabIndex != 0)
navigateToTab(0);
return false;
return true;
,
child: ...,
)
这样,如果选项卡的导航堆栈有多个屏幕,则会弹出该屏幕。如果用户在选项卡的根屏幕并按回,用户将被发送到主选项卡。如果用户在主选项卡的根屏幕并按下回,Flutter 将处理并退出应用程序。
【讨论】:
以上是关于如何在 Flutter 的底部导航中处理后退导航的主要内容,如果未能解决你的问题,请参考以下文章