Appearance
源码:labs/flutter/host/lib/topics/memory_lifecycle/flutter_lifecycle_observer/lifecycle_observer_page.dart
- 原始路径:
labs/flutter/host/lib/topics/memory_lifecycle/flutter_lifecycle_observer/lifecycle_observer_page.dart - 类型:
dart
dart
import 'package:flutter/material.dart';
import '../../../l10n/l10n.dart';
class LifecycleObserverPage extends StatefulWidget {
const LifecycleObserverPage({super.key});
@override
State<LifecycleObserverPage> createState() => _LifecycleObserverPageState();
}
class _LifecycleObserverPageState extends State<LifecycleObserverPage>
with WidgetsBindingObserver {
final List<String> _logs = <String>[];
final TextEditingController _textController = TextEditingController();
int _buildCount = 0;
int _counter = 0;
int _childVersion = 0;
String _lastDetailResult = '';
void _append(String message) {
if (!mounted) {
_appendDirect(message);
return;
}
setState(() {
_appendDirect(message);
});
}
void _appendDirect(String message) {
_logs.insert(0, '[${DateTime.now().toIso8601String()}] $message');
}
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
_appendDirect('initState');
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
_append('didChangeDependencies');
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
_append('AppLifecycleState.$state');
}
@override
void deactivate() {
_appendDirect('deactivate');
super.deactivate();
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
_appendDirect('dispose');
_textController.dispose();
super.dispose();
}
Future<void> _openDetailPage() async {
_append(context.l10n.openDetailPage);
final result = await Navigator.of(context).push<String>(
MaterialPageRoute<String>(builder: (_) => const _LifecycleDetailPage()),
);
if (!mounted) return;
setState(() {
_lastDetailResult = result ?? context.l10n.lifecycleDetailNoResult;
_appendDirect(context.l10n.lifecycleLogDetailResult(_lastDetailResult));
});
}
@override
Widget build(BuildContext context) {
_buildCount += 1;
_appendDirect(context.l10n.lifecycleLogBuild(_buildCount));
return Scaffold(
appBar: AppBar(title: Text(context.l10n.lifecycleAppBarTitle)),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(context.l10n.lifecycleBuildCount(_buildCount)),
Text(context.l10n.lifecycleCounter(_counter)),
Text(
_lastDetailResult.isEmpty
? context.l10n.lifecycleNoDetailResult
: context.l10n.lifecycleLastDetailResult(_lastDetailResult),
),
const SizedBox(height: 12),
TextField(
controller: _textController,
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: context.l10n.lifecycleTextFieldLabel,
),
),
const SizedBox(height: 12),
Wrap(
spacing: 12,
runSpacing: 12,
children: <Widget>[
ElevatedButton(
onPressed: () => setState(() {
_counter += 1;
}),
child: Text(context.l10n.lifecycleBtnRebuild),
),
ElevatedButton(
onPressed: _openDetailPage,
child: Text(context.l10n.openDetailPage),
),
ElevatedButton(
onPressed: () => setState(() {
_childVersion += 1;
_appendDirect(
context.l10n.lifecycleLogReplaceChild(_childVersion),
);
}),
child: Text(context.l10n.lifecycleBtnReplaceChild),
),
],
),
const SizedBox(height: 16),
StatefulColorChip(key: ValueKey<int>(_childVersion)),
const SizedBox(height: 16),
Text(
context.l10n.lifecycleEventLogTitle,
style: const TextStyle(fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
Expanded(
child: ListView.builder(
itemCount: _logs.length,
itemBuilder: (context, index) => Text('• ${_logs[index]}'),
),
),
],
),
),
);
}
}
class StatefulColorChip extends StatefulWidget {
const StatefulColorChip({super.key});
@override
State<StatefulColorChip> createState() => _StatefulColorChipState();
}
class _StatefulColorChipState extends State<StatefulColorChip> {
static const List<Color> _colors = <Color>[
Colors.blue,
Colors.green,
Colors.deepOrange,
Colors.purple,
];
int _index = 0;
@override
void initState() {
super.initState();
debugPrint('StatefulColorChip initState key=${widget.key}');
}
@override
void deactivate() {
debugPrint('StatefulColorChip deactivate key=${widget.key}');
super.deactivate();
}
@override
void dispose() {
debugPrint('StatefulColorChip dispose key=${widget.key}');
super.dispose();
}
@override
Widget build(BuildContext context) {
final color = _colors[_index % _colors.length];
return DecoratedBox(
decoration: BoxDecoration(
color: color.withValues(alpha: 0.15),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: color),
),
child: Padding(
padding: const EdgeInsets.all(12),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(context.l10n.lifecycleChildKey('${widget.key}')),
const SizedBox(width: 12),
ElevatedButton(
onPressed: () => setState(() {
_index += 1;
}),
child: Text(context.l10n.lifecycleBtnChangeChild),
),
],
),
),
);
}
}
class _LifecycleDetailPage extends StatelessWidget {
const _LifecycleDetailPage();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(context.l10n.lifecycleDetailTitle)),
body: Center(
child: ElevatedButton(
onPressed: () => Navigator.of(context).pop(
'detail-pop-at-${DateTime.now().hour}:${DateTime.now().minute}:${DateTime.now().second}',
),
child: Text(context.l10n.lifecycleBtnPopResult),
),
),
);
}
}