Ответ 1
Наиболее распространенный случай, когда вы захотите сделать это, если у вас запущена анимация и вы не хотите использовать ресурсы в фоновом режиме. В этом случае вы должны расширить свой State
с помощью TickerProviderStateMixin
и использовать свой State
в качестве аргумента vsync
для AnimationController
. Flutter позаботится о том, чтобы вызывать слушателей контроллера анимации только тогда, когда видимо ваше State
.
Если вы хотите, чтобы State
, которые живут в вашем PageRoute
, чтобы быть утилизированы, когда PageRoute
затемняется другим содержимым, вы можете передать maintainState
аргумент false
для вашего PageRoute
конструктора. Если вы сделаете это, ваше State
сбросит себя (и его дочерние initState
), когда оно будет скрыто, и ему придется пересоздать себя в initState
используя свойства, переданные в качестве аргументов конструктора его widget
. Вы можете использовать модель или класс контроллера, или PageStorage
, чтобы хранить информацию о прогрессе пользователя, если вы не хотите полного сброса.
Вот пример приложения, которое демонстрирует эти концепции.
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,
),
],
),
);
}
}