如何使用 Flutter 的 onWillpop 实现 BottomNavigationBar 页面过渡?
How do I make BottomNavigationBar page transition with Flutter's onWillpop?
我在 Flutter 项目中使用 BottomNavigationBar。
这个问题针对第 30 行“//TODO:回到 FirstTab”。
当用户位于 SecondTab 或 ThirdTab 并且按下 Android 设备中的 BackButton 时,我希望用户转到 FirstTab。
现在,在 onWillpopScope 中,有一个可以弹出的过程。当用户在 NextPage 时使用。
然后,当用户不在 FirstTab(SecondTab 或 ThirdTab)中且不在 NextTab 中时,我想将他移动到 onWillpopScope 中的 FirstTab。 (我想强制 BottomNavigationBar 切换。)
我该如何描述呢?请告诉我。
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<GlobalKey<NavigatorState>> navigatorKeys = [
GlobalKey<NavigatorState>(),
GlobalKey<NavigatorState>(),
GlobalKey<NavigatorState>(),
];
@override
Widget build(BuildContext context) {
int currentIndex = 0;
return MaterialApp(
home: WillPopScope(
onWillPop: () async {
final isFirstRouteInCurrentTab = await navigatorKeys[currentIndex].currentState.maybePop();
if (isFirstRouteInCurrentTab) {
if (currentIndex != 0) {
//TODO: back to the FirstTab
return false;
}
}
return isFirstRouteInCurrentTab;
},
child: CupertinoTabScaffold(
tabBar: CupertinoTabBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(label: 'Home', icon: Icon(Icons.home)),
BottomNavigationBarItem(label: 'Search', icon: Icon(Icons.search)),
BottomNavigationBarItem(label: 'Setting', icon: Icon(Icons.settings)),
],
onTap: (index) {
// back home only if not switching tab
if (currentIndex == index) {
switch (index) {
case 0:
navigatorKeys[index].currentState.popUntil((route) => route.isFirst);
break;
case 1:
navigatorKeys[index].currentState.popUntil((route) => route.isFirst);
break;
case 2:
navigatorKeys[index].currentState.popUntil((route) => route.isFirst);
break;
}
}
currentIndex = index;
},
currentIndex: currentIndex,
),
tabBuilder: (BuildContext context, int index) {
return CupertinoTabView(
navigatorKey: navigatorKeys[index],
builder: (BuildContext context) {
switch (index) {
case 0:
return FirstTab();
case 1:
return SecondTab();
case 2:
return ThirdTab();
default:
return FirstTab();
}
},
);
},
),
),
);
}
}
class FirstTab extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('first page now'),
),
backgroundColor: Colors.red[200],
child: Center(
child: CupertinoButton(
child: const Text('Next'),
onPressed: () {
Navigator.of(context).push(CupertinoPageRoute(builder: (context) => NextPage()));
},
),
),
);
}
}
//Different color from Firsttab
class SecondTab extends StatelessWidget {}
//Different color from Firsttab
class ThirdTab extends StatelessWidget {}
class NextPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('second page now'),
),
backgroundColor: Colors.white,
child: Center(
child: CupertinoButton(
child: const Text('Back'),
onPressed: () {
Navigator.of(context).pop();
},
),
),
);
}
}
第一步
int currentIndex = 0
;
至 class 成员
下一个
//TODO: back to the FirstTab
setState((){
currentIndex = 0;
});
你可以试试看docs.
我会在这里继续。首先你需要创建一个控制器
final CupertinoTabController _controller = CupertinoTabController();
并像这样添加到您的 CupertinoTabScaffold
CupertinoTabScaffold(
...
controller: _controller,
)
最后你把页面改成这样:
_controller.index = 0,
(这就是 Flutter 中 get 和 set 的工作方式)
我在 Flutter 项目中使用 BottomNavigationBar。 这个问题针对第 30 行“//TODO:回到 FirstTab”。 当用户位于 SecondTab 或 ThirdTab 并且按下 Android 设备中的 BackButton 时,我希望用户转到 FirstTab。 现在,在 onWillpopScope 中,有一个可以弹出的过程。当用户在 NextPage 时使用。 然后,当用户不在 FirstTab(SecondTab 或 ThirdTab)中且不在 NextTab 中时,我想将他移动到 onWillpopScope 中的 FirstTab。 (我想强制 BottomNavigationBar 切换。) 我该如何描述呢?请告诉我。
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<GlobalKey<NavigatorState>> navigatorKeys = [
GlobalKey<NavigatorState>(),
GlobalKey<NavigatorState>(),
GlobalKey<NavigatorState>(),
];
@override
Widget build(BuildContext context) {
int currentIndex = 0;
return MaterialApp(
home: WillPopScope(
onWillPop: () async {
final isFirstRouteInCurrentTab = await navigatorKeys[currentIndex].currentState.maybePop();
if (isFirstRouteInCurrentTab) {
if (currentIndex != 0) {
//TODO: back to the FirstTab
return false;
}
}
return isFirstRouteInCurrentTab;
},
child: CupertinoTabScaffold(
tabBar: CupertinoTabBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(label: 'Home', icon: Icon(Icons.home)),
BottomNavigationBarItem(label: 'Search', icon: Icon(Icons.search)),
BottomNavigationBarItem(label: 'Setting', icon: Icon(Icons.settings)),
],
onTap: (index) {
// back home only if not switching tab
if (currentIndex == index) {
switch (index) {
case 0:
navigatorKeys[index].currentState.popUntil((route) => route.isFirst);
break;
case 1:
navigatorKeys[index].currentState.popUntil((route) => route.isFirst);
break;
case 2:
navigatorKeys[index].currentState.popUntil((route) => route.isFirst);
break;
}
}
currentIndex = index;
},
currentIndex: currentIndex,
),
tabBuilder: (BuildContext context, int index) {
return CupertinoTabView(
navigatorKey: navigatorKeys[index],
builder: (BuildContext context) {
switch (index) {
case 0:
return FirstTab();
case 1:
return SecondTab();
case 2:
return ThirdTab();
default:
return FirstTab();
}
},
);
},
),
),
);
}
}
class FirstTab extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('first page now'),
),
backgroundColor: Colors.red[200],
child: Center(
child: CupertinoButton(
child: const Text('Next'),
onPressed: () {
Navigator.of(context).push(CupertinoPageRoute(builder: (context) => NextPage()));
},
),
),
);
}
}
//Different color from Firsttab
class SecondTab extends StatelessWidget {}
//Different color from Firsttab
class ThirdTab extends StatelessWidget {}
class NextPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('second page now'),
),
backgroundColor: Colors.white,
child: Center(
child: CupertinoButton(
child: const Text('Back'),
onPressed: () {
Navigator.of(context).pop();
},
),
),
);
}
}
第一步
int currentIndex = 0
;
至 class 成员
下一个
//TODO: back to the FirstTab
setState((){
currentIndex = 0;
});
你可以试试看docs.
我会在这里继续。首先你需要创建一个控制器
final CupertinoTabController _controller = CupertinoTabController();
并像这样添加到您的 CupertinoTabScaffold
CupertinoTabScaffold(
...
controller: _controller,
)
最后你把页面改成这样:
_controller.index = 0,
(这就是 Flutter 中 get 和 set 的工作方式)