dea*_*zvi 10 timer dart flutter
我需要创建一个应用程序,在一段时间不活动后将用户导航到。
我尝试将我的应用程序包装在 GestureDetector 中并在指定时间段后运行计时器,如下所示,但它不起作用:
class _MyAppState extends State<MyApp> {
Timer _timer;
@override
void initState() {
super.initState();
_initializeTimer();
}
void _initializeTimer() {
_timer = Timer.periodic(const Duration(seconds: 20), (_) => _logOutUser);
}
void _logOutUser() {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => WelcomePage()));
_timer.cancel();
}
void _handleUserInteraction([_]) {
if (!_timer.isActive) {
return;
}
_timer.cancel();
_initializeTimer();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: _handleUserInteraction,
onPanDown: _handleUserInteraction,
child: MaterialApp(
title: 'Hello',
home: WelcomePage(),
routes: <String, WidgetBuilder>{
'/welcome': (BuildContext context) => new WelcomePage(),
'/login': (BuildContext context) => new LoginPage(),
},
debugShowCheckedModeBanner: false,
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是在我的 flutter 应用程序中一段时间不活动后,我应该如何最好地实现运行功能?
小智 9
FWIW,我GestureDetector按照建议尝试使用 a ,但没有按预期工作。问题是当没有活动时,我收到了连续的手势流。这包括当我尝试更严格的 onTap: 回调时。
我在模拟器上的调试模式下看到了这一点。我没有进一步试验以查看真实手机是否表现出相同的行为,因为即使它们现在没有,将来也可能:显然没有规范保证 GestureDetector不会收到虚假事件。对于不活动超时等与安全相关的事情,这是不可接受的。
对于我的用例,我决定改为检测应用程序何时不可见超过设定的时间是可以的。我对预期用途的推理是,真正的危险是当应用程序不可见时,他们忘记了它在那里。
设置这种不活动超时非常容易。我安排startKeepAlive()在应用程序访问敏感信息的那一刻(例如在输入密码后)打电话。对于我的使用,超时后直接退出应用程序就可以了;显然,如果需要,可以变得更复杂。Anyhoo,这是相关的代码:
const _inactivityTimeout = Duration(seconds: 10);
Timer _keepAliveTimer;
void _keepAlive(bool visible) {
_keepAliveTimer?.cancel();
if (visible) {
_keepAliveTimer = null;
} else {
_keepAliveTimer = Timer(_inactivityTimeout, () => exit(0));
}
}
class _KeepAliveObserver extends WidgetsBindingObserver {
@override didChangeAppLifecycleState(AppLifecycleState state) {
switch(state) {
case AppLifecycleState.resumed:
_keepAlive(true);
break;
case AppLifecycleState.inactive:
case AppLifecycleState.paused:
case AppLifecycleState.detached:
_keepAlive(false); // Conservatively set a timer on all three
break;
}
}
}
/// Must be called only when app is visible, and exactly once
void startKeepAlive() {
assert(_keepAliveTimer == null);
_keepAlive(true);
WidgetsBinding.instance.addObserver(_KeepAliveObserver());
}
Run Code Online (Sandbox Code Playgroud)
在生产中,我可能会延长超时时间:-)
这是我的解决方案。一些细节:
Navigator在家里应用程序的窗口小部件,因此它可以访问导航之外MaterialApp通过GlobalKey;GestureDetector行为设置为HitTestBehavior.translucent将点击传播到其他小部件;Timer.periodic为此目的。周期性定时器用于重复执行回调(例如,每10秒);_logOutUser调用回调后,定时器被取消(如果有的话),每条路由都被弹出并推送新路由。class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final _navigatorKey = GlobalKey<NavigatorState>();
Timer _timer;
@override
void initState() {
super.initState();
_initializeTimer();
}
void _initializeTimer() {
if (_timer != null) {
_timer.cancel();
}
_timer = Timer(const Duration(seconds: 3), _logOutUser);
}
void _logOutUser() {
_timer?.cancel();
_timer = null;
// Popping all routes and pushing welcome screen
_navigatorKey.currentState.pushNamedAndRemoveUntil('welcome', (_) => false);
}
void _handleUserInteraction([_]) {
_initializeTimer();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: _handleUserInteraction,
onPanDown: _handleUserInteraction,
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Navigator(
initialRoute: 'welcome',
key: _navigatorKey,
onGenerateRoute: (settings) {
return MaterialPageRoute(
builder: (context) {
return Scaffold(
appBar: AppBar(),
body: SafeArea(
child: Text(settings.name)
),
floatingActionButton: FloatingActionButton(
onPressed: () => Navigator.of(context).pushNamed('test'),
),
);
}
);
},
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
对于想要严格回答标题问题(“如何在 Flutter 中一段时间不活动后执行函数”)的人来说,这是完整的解决方案:
@覆盖
无效的初始化状态(){
super.initState();
_initializeTimer();
}
// 启动/重启定时器
void _initializeTimer() {
如果(_timer != null){
_timer.cancel();
}
// 5 分钟后设置动作
_timer = Timer(const Duration(minutes: 5), () => _handleInactivity());
}
无效_handleInactivity(){
_timer?.cancel();
_timer = 空;
// TODO: 在这里输入你想要的代码
}
| 归档时间: |
|
| 查看次数: |
6594 次 |
| 最近记录: |