feat: 两次退出确认

This commit is contained in:
guozhigq
2023-08-30 09:18:34 +08:00
parent 52e44fb95b
commit fceb55aaa3
2 changed files with 63 additions and 46 deletions

View File

@ -1,5 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
@ -53,6 +54,7 @@ class MainController extends GetxController {
final StreamController<bool> bottomBarStream = final StreamController<bool> bottomBarStream =
StreamController<bool>.broadcast(); StreamController<bool>.broadcast();
Box setting = GStrorage.setting; Box setting = GStrorage.setting;
DateTime? _lastPressedAt;
@override @override
void onInit() { void onInit() {
@ -61,4 +63,16 @@ class MainController extends GetxController {
Utils.checkUpdata(); Utils.checkUpdata();
} }
} }
Future<bool> onBackPressed(BuildContext context) {
if (_lastPressedAt == null ||
DateTime.now().difference(_lastPressedAt!) >
const Duration(seconds: 2)) {
// 两次点击时间间隔超过2秒重新记录时间戳
_lastPressedAt = DateTime.now();
SmartDialog.showToast("再按一次退出Pili");
return Future.value(false); // 不退出应用
}
return Future.value(true); // 退出应用
}
} }

View File

@ -110,55 +110,58 @@ class _MainAppState extends State<MainApp> with SingleTickerProviderStateMixin {
MediaQuery.of(context).size.width * 9 / 16; MediaQuery.of(context).size.width * 9 / 16;
localCache.put('sheetHeight', sheetHeight); localCache.put('sheetHeight', sheetHeight);
localCache.put('statusBarHeight', statusBarHeight); localCache.put('statusBarHeight', statusBarHeight);
return Scaffold( return WillPopScope(
extendBody: true, onWillPop: () => _mainController.onBackPressed(context),
body: FadeTransition( child: Scaffold(
opacity: _fadeAnimation!, extendBody: true,
child: SlideTransition( body: FadeTransition(
position: Tween<Offset>( opacity: _fadeAnimation!,
begin: const Offset(0, 0.5), child: SlideTransition(
end: Offset.zero, position: Tween<Offset>(
).animate( begin: const Offset(0, 0.5),
CurvedAnimation( end: Offset.zero,
parent: _slideAnimation!, ).animate(
curve: Curves.fastOutSlowIn, CurvedAnimation(
reverseCurve: Curves.linear, parent: _slideAnimation!,
curve: Curves.fastOutSlowIn,
reverseCurve: Curves.linear,
),
),
child: PageView(
physics: const NeverScrollableScrollPhysics(),
controller: _pageController,
onPageChanged: (index) {
selectedIndex = index;
setState(() {});
},
children: _mainController.pages,
), ),
),
child: PageView(
physics: const NeverScrollableScrollPhysics(),
controller: _pageController,
onPageChanged: (index) {
selectedIndex = index;
setState(() {});
},
children: _mainController.pages,
), ),
), ),
), bottomNavigationBar: StreamBuilder(
bottomNavigationBar: StreamBuilder( stream: _mainController.bottomBarStream.stream,
stream: _mainController.bottomBarStream.stream, initialData: true,
initialData: true, builder: (context, AsyncSnapshot snapshot) {
builder: (context, AsyncSnapshot snapshot) { return AnimatedSlide(
return AnimatedSlide( curve: Curves.easeInOutCubicEmphasized,
curve: Curves.easeInOutCubicEmphasized, duration: const Duration(milliseconds: 1000),
duration: const Duration(milliseconds: 1000), offset: Offset(0, snapshot.data ? 0 : 1),
offset: Offset(0, snapshot.data ? 0 : 1), child: NavigationBar(
child: NavigationBar( onDestinationSelected: (value) => setIndex(value),
onDestinationSelected: (value) => setIndex(value), selectedIndex: selectedIndex,
selectedIndex: selectedIndex, destinations: <Widget>[
destinations: <Widget>[ ..._mainController.navigationBars.map((e) {
..._mainController.navigationBars.map((e) { return NavigationDestination(
return NavigationDestination( icon: e['icon'],
icon: e['icon'], selectedIcon: e['selectIcon'],
selectedIcon: e['selectIcon'], label: e['label'],
label: e['label'], );
); }).toList(),
}).toList(), ],
], ),
), );
); },
}, ),
), ),
); );
} }