如何创建基于时间的 Flutter 应用程序?

Nic*_*ick 5 lifecycle timer flutter

我需要创建一个登录表单。用户成功登录后,我需要启动某种计时器(例如:3 分钟),因此如果用户对应用程序没有反应,或者如果 Flutter 应用程序状态暂停、暂停或不活动超过 3 分钟,则用户没有反应。该应用程序将转到主登录页面。只要用户与应用程序交互,我就需要取消计时器,并且只需要启动计时器应用程序状态是暂停、暂停或不活动。我怎么做?

我尝试实现“WidgetsBindingObserver”,但它看起来不像我想要的那样工作。如果用户成功输入并在应用程序中导航,则 WidgetsBindingObserver 将失败(错误:小部件的状态对象不再出现在小部件树中)。

我的问题是如何实现基于定时的 Flutter 应用程序生命周期,只要用户与应用程序有交互?如果没有用户交互,生命周期计时器将启动,如果在计时器结束之前有用户交互,则必须取消计时器。

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 (

    );
}

}
Run Code Online (Sandbox Code Playgroud)

Kir*_*kos 6

您可以使用Timer类在 3 分钟不活动后触发注销功能。您可以尝试将整个应用程序包装在一个GestureDetector可以在任何事件上重置计时器的方法中。您只需要确保GestureDetector应用程序中的任何其他s 都使用,HitTestBehavior.translucent以便将事件传播到您的根侦听器。这是一个完整的例子:

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
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

更新:我刚刚发现Listener类在这里可能比GestureDetector. 我个人从未使用过它,但可以随意尝试!查看有关手势文档以获取更多信息。