如何创建基于时间的Flutter应用程序? [英] How do I create a time-based Flutter App?
问题描述
我需要创建一个登录表单.用户成功登录后,我需要启动某种计时器(例如3分钟),因此,如果用户对应用程序或其他字词没有任何反应,则当Flutter应用程序状态暂停,暂停或不活动超过3分钟时.该应用程序将转到主登录页面.只要用户与应用程序进行交互,我就需要取消计时器,而只需要给计时器加注星标,则应用程序的状态将被暂停,暂停或无效.我该怎么办?
I need to create a login form. After user successfully login than I need to start some kind of timer (ex: 3 min), so if user has no reaction to app or other word if flutter app state is paused, suspended or inactive more than 3 min. the app will goto main login page. As long as user has interaction with app I need to cancel the timer and only I need to star timer app state is paused, suspended or inactive. How do I do that?
我尝试实现"WidgetsBindingObserver",但是它看起来并没有按照我的要求工作.如果用户成功输入并在应用程序中导航,则WidgetsBindingObserver会失败(错误:窗口小部件树中不再显示的窗口小部件的状态对象).
I try to implement the "WidgetsBindingObserver" but its look like is not working as I wanted. If user enters successfully and navigate in app the WidgetsBindingObserver fail (error: state object for widget that no longer appears in the widget tree).
我的问题是,只要用户与应用程序进行交互,如何实现基于时间的颤动应用程序生命周期?如果没有用户交互,则生命周期计时器将启动,并且如果在计时器结束之前存在用户交互,则必须取消该计时器.
My question is how to implement timed-based flutter app lifecycle, as long as user has interaction with the app? If no user interaction the lifecycle timer will start and if before the timer ends there is a user interaction the timer must be canceled.
class _MyUserHomePageState extends State<MyUserHomePage> with WidgetsBindingObserver {
AppLifecycleState _appLifecycleState;
@override
void initState() {
_appStatePasue = false;
WidgetsBinding.instance.addObserver(this);
super.initState();
}
// TODO: DID_CHANGE_APP_LIFE_CYCLE
void didChangeAppLifecycleState(AppLifecycleState state) {
setState(() {
_appLifecycleState = state;
if(_appLifecycleState == AppLifecycleState.paused ||
_appLifecycleState == AppLifecycleState.inactive ||
_appLifecycleState == AppLifecycleState.suspending) {
_appStatePasue = true;
print("timer---fired: $_appLifecycleState");
_timer = Timer.periodic(Duration(minutes: 1), _capitalCallback);
print(_appLifecycleState);
} else {
_appStatePasue = false;
}
});
}
// TODO: APP_LIFE_CYCLE__CALLBACK
void _capitalCallback(_timer) {
if(_appStatePasue == true) {
_timer.cancel();
print("return---main---page: $_appLifecycleState");
setState(() {
Navigator.push(
context,
SlideRightRoute(widget: MyApp())
);
});
} else {
_timer.cancel();
print("timer---canceled: $_appLifecycleState");
}
}
@override
void dispose() {
super.dispose();
}
@override
void onDeactivate() {
super.deactivate();
}
@override
Widget build(BuildContext context) {
return new Scaffold (
);
}
}
推荐答案
You can use the Timer class to trigger a log out function after 3 minutes of inactivity. Something you can try is to wrap your entire app in a GestureDetector
that resets the timer on any event. You'd just have to make sure that any other GestureDetector
s in your app use HitTestBehavior.translucent
so the events are propagated to your root listener. Here's a full example:
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) => AppRoot();
}
class AppRoot extends StatefulWidget {
@override
AppRootState createState() => AppRootState();
}
class AppRootState extends State<AppRoot> {
Timer _timer;
@override
void initState() {
super.initState();
_initializeTimer();
}
void _initializeTimer() {
_timer = Timer.periodic(const Duration(minutes: 3), (_) => _logOutUser);
}
void _logOutUser() {
// Log out the user if they're logged in, then cancel the timer.
// You'll have to make sure to cancel the timer if the user manually logs out
// and to call _initializeTimer once the user logs in
_timer.cancel();
}
// You'll probably want to wrap this function in a debounce
void _handleUserInteraction([_]) {
if (!_timer.isActive) {
// This means the user has been logged out
return;
}
_timer.cancel();
_initializeTimer();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: _handleUserInteraction,
onPanDown: _handleUserInteraction,
onScaleStart: _handleUserInteraction,
// ... repeat this for all gesture events
child: MaterialApp(
// ... from here it's just your normal app,
// Remember that any GestureDetector within your app must have
// HitTestBehavior.translucent
),
);
}
}
更新:我刚刚发现了 Listener 类,它可能会带来更多比 GestureDetector
更有意义.我个人从未使用过它,但请随时尝试!请查看有关手势的文档以获取更多信息.
UPDATE: I just discovered the Listener class which might make more sense here than the GestureDetector
. I've personally never used it, but feel free to experiment! Check out the documentation on gestures for more info.
这篇关于如何创建基于时间的Flutter应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!