Flutter 如何在颤振中分离一次点击和两次点击后退按钮?
当我在Flutter 如何在颤振中分离一次点击和两次点击后退按钮?,flutter,double-click,cupertinotabbar,Flutter,Double Click,Cupertinotabbar,当我在CupertinoTabbar中双击后退按钮时,我正在尝试创建一个退出应用程序的功能 尽管我已经应用了各种功能,如DoubleBackToCloseApp插件或WillPopScope,但每当我点击后退按钮时,都会出现一条退出消息 因此,我想构建如下代码: class TabPage extends StatefulWidget { final FirebaseUser currentUser; TabPage(this.currentUser); @override
CupertinoTabbar
中双击后退按钮时,我正在尝试创建一个退出应用程序的功能
尽管我已经应用了各种功能,如DoubleBackToCloseApp
插件或WillPopScope
,但每当我点击后退按钮时,都会出现一条退出消息
因此,我想构建如下代码:
class TabPage extends StatefulWidget {
final FirebaseUser currentUser;
TabPage(this.currentUser);
@override
_TabPageState createState() => _TabPageState();
}
class _TabPageState extends State<TabPage> {
int _selectedIndex = 0;
static const snackBarDuration = Duration(seconds: 1);
DateTime backbuttonpressedTime;
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
final GlobalKey<NavigatorState> homeTabNavKey = GlobalKey<NavigatorState>();
final GlobalKey<NavigatorState> groupTabNavKey = GlobalKey<NavigatorState>();
final GlobalKey<NavigatorState> feedTabNavKey = GlobalKey<NavigatorState>();
final GlobalKey<NavigatorState> userTabNavKey = GlobalKey<NavigatorState>();
@override
void initState() {
_firebaseMessaging.onTokenRefresh.listen(sendTokenToServer);
_firebaseMessaging.getToken();
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
return !await currentNavigatorKey().currentState.maybePop();
},
child: Scaffold(
body: WillPopScope(
onWillPop: _onWillPop,
child: CupertinoTabScaffold(
tabBar: CupertinoTabBar(
activeColor: Theme
.of(context)
.colorScheme
.mainColor,
inactiveColor: Theme
.of(context)
.colorScheme
.greyColor,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home)),
BottomNavigationBarItem(
icon: Icon(Icons.group)),
BottomNavigationBarItem(
icon: Icon(Icons.favorite_border)),
BottomNavigationBarItem(
icon: Icon(Icons.account_circle)),
],
onTap: (index) {
// back home only if not switching tab
if (_selectedIndex == index) {
switch (index) {
case 0:
homeTabNavKey.currentState.popUntil((r) => r.isFirst);
break;
case 1:
groupTabNavKey.currentState.popUntil((r) => r.isFirst);
break;
case 2:
feedTabNavKey.currentState.popUntil((r) => r.isFirst);
break;
case 3:
userTabNavKey.currentState.popUntil((r) => r.isFirst);
break;
}
}
_selectedIndex = index;
},
),
tabBuilder: (BuildContext context, int index) {
switch (index) {
case 0:
return CupertinoTabView(
navigatorKey: homeTabNavKey,
builder: (BuildContext context) => HomePage(),
);
break;
case 1:
return CupertinoTabView(
navigatorKey: groupTabNavKey,
builder: (BuildContext context) => GroupPage(),
);
break;
case 2:
return CupertinoTabView(
navigatorKey: feedTabNavKey,
builder: (BuildContext context) => FeedPage(widget.currentUser),
);
break;
case 3:
return CupertinoTabView(
navigatorKey: userTabNavKey,
builder: (BuildContext context) =>
UserPage(widget.currentUser?.uid),
);
break;
}
return null;
},
),
),
),
);
}
void sendTokenToServer(String fcmToken) {
print('Token: $fcmToken');
Firestore.instance.collection('pushtokens')
.document(widget.currentUser.uid)
.setData({
'pushToken': fcmToken
});
}
GlobalKey<NavigatorState> currentNavigatorKey() {
switch (_selectedIndex) {
case 0:
return homeTabNavKey;
break;
case 1:
return groupTabNavKey;
break;
case 2:
return feedTabNavKey;
break;
case 3:
return userTabNavKey;
break;
}
return null;
}
//
Future<bool> _onWillPop() async {
DateTime currentTime = DateTime.now();
//Statement 1 Or statement2
bool backButton = backbuttonpressedTime == null ||
currentTime.difference(backbuttonpressedTime) > Duration(seconds: 2);
if (backButton) {
backbuttonpressedTime = currentTime;
Fluttertoast.showToast(
msg: "Double Click to exit app",
backgroundColor: Colors.black,
textColor: Colors.white);
return false;
}
return true;
}
}
- 只需点击后退按钮一次,返回页面之前
- 几秒钟内轻触两次,退出应用程序
class TabPage extends StatefulWidget {
final FirebaseUser currentUser;
TabPage(this.currentUser);
@override
_TabPageState createState() => _TabPageState();
}
class _TabPageState extends State<TabPage> {
int _selectedIndex = 0;
static const snackBarDuration = Duration(seconds: 1);
DateTime backbuttonpressedTime;
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
final GlobalKey<NavigatorState> homeTabNavKey = GlobalKey<NavigatorState>();
final GlobalKey<NavigatorState> groupTabNavKey = GlobalKey<NavigatorState>();
final GlobalKey<NavigatorState> feedTabNavKey = GlobalKey<NavigatorState>();
final GlobalKey<NavigatorState> userTabNavKey = GlobalKey<NavigatorState>();
@override
void initState() {
_firebaseMessaging.onTokenRefresh.listen(sendTokenToServer);
_firebaseMessaging.getToken();
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
return !await currentNavigatorKey().currentState.maybePop();
},
child: Scaffold(
body: WillPopScope(
onWillPop: _onWillPop,
child: CupertinoTabScaffold(
tabBar: CupertinoTabBar(
activeColor: Theme
.of(context)
.colorScheme
.mainColor,
inactiveColor: Theme
.of(context)
.colorScheme
.greyColor,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home)),
BottomNavigationBarItem(
icon: Icon(Icons.group)),
BottomNavigationBarItem(
icon: Icon(Icons.favorite_border)),
BottomNavigationBarItem(
icon: Icon(Icons.account_circle)),
],
onTap: (index) {
// back home only if not switching tab
if (_selectedIndex == index) {
switch (index) {
case 0:
homeTabNavKey.currentState.popUntil((r) => r.isFirst);
break;
case 1:
groupTabNavKey.currentState.popUntil((r) => r.isFirst);
break;
case 2:
feedTabNavKey.currentState.popUntil((r) => r.isFirst);
break;
case 3:
userTabNavKey.currentState.popUntil((r) => r.isFirst);
break;
}
}
_selectedIndex = index;
},
),
tabBuilder: (BuildContext context, int index) {
switch (index) {
case 0:
return CupertinoTabView(
navigatorKey: homeTabNavKey,
builder: (BuildContext context) => HomePage(),
);
break;
case 1:
return CupertinoTabView(
navigatorKey: groupTabNavKey,
builder: (BuildContext context) => GroupPage(),
);
break;
case 2:
return CupertinoTabView(
navigatorKey: feedTabNavKey,
builder: (BuildContext context) => FeedPage(widget.currentUser),
);
break;
case 3:
return CupertinoTabView(
navigatorKey: userTabNavKey,
builder: (BuildContext context) =>
UserPage(widget.currentUser?.uid),
);
break;
}
return null;
},
),
),
),
);
}
void sendTokenToServer(String fcmToken) {
print('Token: $fcmToken');
Firestore.instance.collection('pushtokens')
.document(widget.currentUser.uid)
.setData({
'pushToken': fcmToken
});
}
GlobalKey<NavigatorState> currentNavigatorKey() {
switch (_selectedIndex) {
case 0:
return homeTabNavKey;
break;
case 1:
return groupTabNavKey;
break;
case 2:
return feedTabNavKey;
break;
case 3:
return userTabNavKey;
break;
}
return null;
}
//
Future<bool> _onWillPop() async {
DateTime currentTime = DateTime.now();
//Statement 1 Or statement2
bool backButton = backbuttonpressedTime == null ||
currentTime.difference(backbuttonpressedTime) > Duration(seconds: 2);
if (backButton) {
backbuttonpressedTime = currentTime;
Fluttertoast.showToast(
msg: "Double Click to exit app",
backgroundColor: Colors.black,
textColor: Colors.white);
return false;
}
return true;
}
}
class选项卡页扩展StatefulWidget{
最终FirebaseUser当前用户;
TabPage(此.currentUser);
@凌驾
_TabPageState createState()=>TabPageState();
}
类_TabPageState扩展状态{
int _selectedIndex=0;
静态常数snackBarDuration=持续时间(秒:1);
DateTime backbuttonpressedTime;
最终FirebaseMessaging_FirebaseMessaging=FirebaseMessaging();
最终GlobalKey homeTabNavKey=GlobalKey();
final GlobalKey groupTabNavKey=GlobalKey();
最终GlobalKey feedTabNavKey=GlobalKey();
最终GlobalKey userTabNavKey=GlobalKey();
@凌驾
void initState(){
_firebaseMessaging.onTokenRefresh.listen(sendTokenToServer);
_firebaseMessaging.getToken();
}
@凌驾
小部件构建(构建上下文){
返回式示波器(
onWillPop:()异步{
return!wait currentNavigatorKey().currentState.maybePop();
},
孩子:脚手架(
正文:Willposcope(
onWillPop:_onWillPop,
孩子:库珀提诺巴塞弗德(
tabBar:CupertinoTabBar(
活动颜色:主题
.of(上下文)
.配色方案
.mainColor,
彩色:主题
.of(上下文)
.配色方案
greyColor先生,
项目:[
底部导航气压计(
图标:图标(Icons.home)),
底部导航气压计(
图标:图标(Icons.group)),
底部导航气压计(
图标:图标(Icons.favorite_border)),
底部导航气压计(
图标:图标(Icons.account_circle)),
],
onTap:(索引){
//仅当不切换选项卡时返回主页
如果(_selectedIndex==索引){
开关(索引){
案例0:
homeTabNavKey.currentState.popUntil((r)=>r.isFirst);
打破
案例1:
groupTabNavKey.currentState.PopIntil((r)=>r.isFirst);
打破
案例2:
feedTabNavKey.currentState.popUntil((r)=>r.isFirst);
打破
案例3:
userTabNavKey.currentState.popUntil((r)=>r.isFirst);
打破
}
}
_selectedIndex=索引;
},
),
tabBuilder:(BuildContext,int-index){
开关(索引){
案例0:
返回CupertinoTabView(
导航工作:homeTabNavKey,
生成器:(BuildContext上下文)=>HomePage(),
);
打破
案例1:
返回CupertinoTabView(
navigatorKey:groupTabNavKey,
生成器:(BuildContext上下文)=>GroupPage(),
);
打破
案例2:
返回CupertinoTabView(
导航工作:feedTabNavKey,
生成器:(BuildContext上下文)=>FeedPage(widget.currentUser),
);
打破
案例3:
返回CupertinoTabView(
navigatorKey:userTabNavKey,
生成器:(BuildContext上下文)=>
用户页面(widget.currentUser?.uid),
);
打破
}
返回null;
},
),
),
),
);
}
void sendtoketoserver(字符串fcmToken){
打印('Token:$fcmToken');
Firestore.instance.collection('pushtokens')
.document(widget.currentUser.uid)
.setData({
“pushToken”:fcmToken
});
}
GlobalKey currentNavigatorKey(){
开关(_selectedIndex){
案例0:
返回homeTabNavKey;
打破
案例1:
返回groupTabNavKey;
打破
案例2:
返回feedTabNavKey;
打破
案例3:
返回userTabNavKey;
打破
}
返回null;
}
//
Future\u onWillPop()异步{
DateTime currentTime=DateTime.now();
//报表1或报表2
bool backButton=backbuttonpressedTime==null||
当前时间差(backbuttonpressedTime)>持续时间(秒:2);
如果(后退按钮){
backbuttonpressedTime=当前时间;
烤面包片(
msg:“双击退出应用程序”,
背景颜色:Colors.black,
文本颜色:颜色。白色);
返回false;
}
返回true;
}
}
谢谢大家!
我终于解决了这个问题。
我会发布更新的代码
int backbuttonpressedTime = 0;
Future<bool> _onWillPop() async {
var currentTime = DateTime.now().millisecondsSinceEpoch;
if(!currentNavigatorKey().currentState.canPop()) {
if (currentTime-backbuttonpressedTime < Duration(seconds: 2).inMilliseconds) {
return SystemChannels.platform.invokeMethod('SystemNavigator.pop');
}else{
Fluttertoast.showToast(
msg: "Double Click to exit app",
backgroundColor: Colors.black,
timeInSecForIos: 1,
textColor: Colors.white);
backbuttonpressedTime = currentTime;
return false;
}
}else{
return true;
}
}
int backbuttonpressedTime=0;
Future\u onWillPop()异步{
var currentTime=DateTime.now().millissecondssinceepoch;
如果(!currentNavigatorKey().currentState.canPop()){
如果(currentTime BackButton PressedTime<持续时间(秒:2)。以毫秒为单位){
返回SystemChannels.platform.invokeMethod('SystemNavigator.pop');
}否则{
烤面包片(
msg:“双击退出应用程序”,
背景颜色:Colors.black,
时间:1,
文本颜色:颜色。白色);
文学士