Подтвердить что ты не робот

Flutter: обновить виджеты по возобновлению?

В Flutter есть ли способ обновить виджеты, когда пользователь покидает приложение и возвращается обратно к нему? Мое приложение основано на времени, и было бы полезно обновить время, как только сможете.

4b9b3361

Ответ 1

Вы можете слушать события жизненного цикла

import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';

class LifecycleEventHandler extends WidgetsBindingObserver {
  LifecycleEventHandler({this.resumeCallBack, this.suspendingCallBack});

  final AsyncCallback resumeCallBack;
  final AsyncCallback suspendingCallBack;

  @override
  Future<Null> didChangeAppLifecycleState(AppLifecycleState state) async {
    switch (state) {
      case AppLifecycleState.inactive:
      case AppLifecycleState.paused:
      case AppLifecycleState.suspending:
        await suspendingCallBack();
        break;
      case AppLifecycleState.resumed:
        await resumeCallBack();
        break;
    }
  }
}


class AppWidgetState extends State<AppWidget> {
  void initState() {
    super.initState();

    WidgetsBinding.instance.addObserver(
        new LifecycleEventHandler(resumeCallback(() => setState((){}))
    );
  }
  ...
}

Ответ 2

Используя системный канал:

import 'package:flutter/services.dart';

SystemChannels.lifecycle.setMessageHandler((msg){
  debugPrint('SystemChannels> $msg');
  if(msg==AppLifecycleState.resumed.toString())setState((){});
});

'

Ответ 3

Простой способ:

import 'package:flutter/services.dart';

handleAppLifecycleState() {
    AppLifecycleState _lastLifecyleState;
    SystemChannels.lifecycle.setMessageHandler((msg) {

     print('SystemChannels> $msg');

        switch (msg) {
          case "AppLifecycleState.paused":
            _lastLifecyleState = AppLifecycleState.paused;
            break;
          case "AppLifecycleState.inactive":
            _lastLifecyleState = AppLifecycleState.inactive;
            break;
          case "AppLifecycleState.resumed":
            _lastLifecyleState = AppLifecycleState.resumed;
            break;
          case "AppLifecycleState.suspending":
            _lastLifecyleState = AppLifecycleState.suspending;
            break;
          default:
        }
    });
  }

просто добавьте handleAppLifecycleState() в вашем init()

ИЛИ ЖЕ

class AppLifecycleReactor extends StatefulWidget {
      const AppLifecycleReactor({ Key key }) : super(key: key);

      @override
      _AppLifecycleReactorState createState() => _AppLifecycleReactorState();
    }

    class _AppLifecycleReactorState extends State<AppLifecycleReactor> with WidgetsBindingObserver {
      @override
      void initState() {
        super.initState();
        WidgetsBinding.instance.addObserver(this);
      }

      @override
      void dispose() {
        WidgetsBinding.instance.removeObserver(this);
        super.dispose();
      }

      AppLifecycleState _notification;

      @override
      void didChangeAppLifecycleState(AppLifecycleState state) {
        setState(() { _notification = state; });
      }

      @override
      Widget build(BuildContext context) {
        return Text('Last notification: $_notification');
      }
    }

Для более подробной информации вы обратитесь к документации

Ответ 4

Для глубокого тестирования, я думаю, что результаты стоит прочитать. Если вам интересно, какой метод вы должны использовать, просто прочитайте ниже: (Проверено на Android)

Существует три способа решения LifeCycle.

  1. WidgetsBindingObserver
  2. SystemChannels.lifecycle
  3. флаттер-андроид-Жизненный цикл-плагин

Основное различие между WidgetsBindingObserver и SystemChannels.lifecycle является то, что WidgetsBindingObserver больше capables Если у вас есть куча виджетов, которые должны слушать Lifecycle. SystemChannels является более низким уровнем, и используется WidgetsBindingObserver.

После нескольких испытаний, если вы используете SystemChannels после runApp и дома виджет с Mixin WidgetsBindingObserver, домашний виджет будет не удалось, потому что SystemChannels.lifecycle.setMessageHandler переопределить метод домой.

Так что, если вы хотите использовать глобальный одиночный метод, перейдите к SystemChannels.lifecycle, другие для WidgetsBindingObserver.

А как насчет третьего метода? Это только для Android, и если вы должны связать свой метод перед runApp, это единственный путь.

Ответ 5

Вот пример того, как наблюдать за состоянием жизненного цикла содержащего действия (Flutter для разработчиков Android):

import 'package:flutter/widgets.dart';

class LifecycleWatcher extends StatefulWidget {
  @override
  _LifecycleWatcherState createState() => _LifecycleWatcherState();
}

class _LifecycleWatcherState extends State<LifecycleWatcher> with WidgetsBindingObserver {
  AppLifecycleState _lastLifecycleState;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    setState(() {
      _lastLifecycleState = state;
    });
  }

  @override
  Widget build(BuildContext context) {
    if (_lastLifecycleState == null)
      return Text('This widget has not observed any lifecycle changes.', textDirection: TextDirection.ltr);

    return Text('The most recent lifecycle state this widget observed was: $_lastLifecycleState.',
        textDirection: TextDirection.ltr);
  }
}

void main() {
  runApp(Center(child: LifecycleWatcher()));
}