À l'heure actuelle, un widget n'a que initeState () qui est déclenché la toute première fois qu'un widget est créé, et dispose (), qui est déclenché lorsque le widget est détruit. Existe-t-il une méthode pour détecter le moment où un widget revient au premier plan? et quand un widget est sur le point d’aller en arrière-plan parce qu’un autre widget vient d’être mis au premier plan? C'est l'équivalent de onResume et onPause déclenchés pour Android, et viewWillAppear et viewWillDisappear pour ios
Le cas le plus courant où vous souhaitez le faire est si vous avez une animation en cours d'exécution et que vous ne voulez pas consommer de ressources en arrière-plan. Dans ce cas, vous devez étendre votre State
avec TickerProviderStateMixin
et utiliser votre State
comme argument vsync
pour le AnimationController
. Flutter prendra soin d'appeler uniquement les écouteurs du contrôleur d'animation lorsque votre State
est visible.
Si vous souhaitez que les State
qui vivent dans votre PageRoute
soient supprimés lorsque le PageRoute
est masqué par un autre contenu, vous pouvez passer un maintainState
argument de false
à votre constructeur PageRoute
. Si vous faites cela, votre State
se réinitialisera (et ses enfants) quand il sera caché et devra se reconstruire dans initState
en utilisant les propriétés passées en arguments constructeur à son widget
. Vous pouvez utiliser un modèle ou une classe de contrôleur, ou PageStorage
, pour conserver les informations de progression de l'utilisateur si vous ne souhaitez pas une réinitialisation complète.
Voici un exemple d'application qui illustre ces concepts.
import 'package:flutter/material.Dart';
void main() {
runApp(new MaterialApp(
onGenerateRoute: (RouteSettings settings) {
if (settings.name == '/') {
return new MaterialPageRoute<Null>(
settings: settings,
builder: (_) => new MyApp(),
maintainState: false,
);
}
return null;
}
));
}
class MyApp extends StatefulWidget {
MyAppState createState() => new MyAppState();
}
class MyAppState extends State<MyApp> with TickerProviderStateMixin {
AnimationController _controller;
@override
void initState() {
print("initState was called");
_controller = new AnimationController(vsync: this)
..repeat(min: 0.0, max: 1.0, period: const Duration(seconds: 1))
..addListener(() {
print('animation value ${_controller.value}');
});
super.initState();
}
@override
void dispose() {
print("dispose was called");
_controller.dispose();
super.dispose();
}
int _counter = 0;
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('home screen')
),
body: new Center(
child: new RaisedButton(
onPressed: () {
setState(() {
_counter++;
});
},
child: new Text('Button pressed $_counter times'),
),
),
floatingActionButton: new FloatingActionButton(
child: new Icon(Icons.remove_red_eye),
onPressed: () {
Navigator.Push(context, new MaterialPageRoute(
builder: (BuildContext context) {
return new MySecondPage(counter: _counter);
},
));
},
),
);
}
}
class MySecondPage extends StatelessWidget {
MySecondPage({ this.counter });
final int counter;
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Certificate of achievement'),
),
body: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
new Icon(Icons.developer_mode, size: 200.0),
new Text(
'Congrats, you clicked $counter times.',
style: Theme.of(context).textTheme.title,
textAlign: TextAlign.center,
),
new Text(
'All your progress has now been lost.',
style: Theme.of(context).textTheme.subhead,
textAlign: TextAlign.center,
),
],
),
);
}
}
Il existe un appelant de classe abstraite WidgetsBindingObserver
https://docs.flutter.io/flutter/widgets/WidgetsBindingObserver-class.html
dans
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
setState(() {
_notification = state;
});
}
il y a "l'état", peut être géré comme
switch(state) {
case AppLifecycleState.resumed:
// Handle this case
break;
case AppLifecycleState.inactive:
// Handle this case
break;
case AppLifecycleState.paused:
// Handle this case
break;
case AppLifecycleState.suspending:
// Handle this case
break;
}