Lifecycle support for Flutter widgets.
StatefulWidget.StatelessWidget(includeDialog).PageView/TabBarViewand it's children.- Nested
PageView. Navigator(Navigator 2.0 pages api).- Child of
ListView/GridView/CustomScrollView.
enumLifecycleEvent {
push,
visible,
active,
inactive,
invisible,
pop,
}- Depend on it
dependencies:
lifecycle: any # replace 'any' with version number- Install it
flutter pub get
- Import it
import 'package:lifecycle/lifecycle.dart';
First of all, you should register an observer in WidgetsApp/MaterialApp, and an observer can only be used by one Navigator, if you have your own Navigator, please use a new instance of LifecycleObserver.
import'package:flutter/material.dart';
import'package:lifecycle/lifecycle.dart';
classMyAppextendsStatelessWidget {
@overrideWidgetbuild(BuildContext context) {
returnMaterialApp(
navigatorObservers: [defaultLifecycleObserver],
...
);
}
}- StatefulWidget
- Use mixin(Recommend)
import'package:flutter/material.dart';
import'package:lifecycle/lifecycle.dart';
// mixin LifecycleAware and LifecycleMixin on Stateclass_StateextendsState<MyStatefulWidget> withLifecycleAware, LifecycleMixin {
@overridevoidonLifecycleEvent(LifecycleEvent event) {
print(event);
}
@overrideWidgetbuild(BuildContext context) {
returnScaffold();
}
}- Use wrapper
import'package:flutter/material.dart';
import'package:lifecycle/lifecycle.dart';
// Wrap widget with LifecycleWrapperclass_StateextendsState<MyStatefulWidget> {
@overrideWidgetbuild(BuildContext context) {
returnLifecycleWrapper(
onLifecycleEvent: (event) {
print(event);
},
child:Scaffold(),
);
}
}- StatelessWidget/Dialog
import'package:flutter/material.dart';
import'package:lifecycle/lifecycle.dart';
// Normal StatelessWidgetclassMyStatelessWidgetextendsStatelessWidget {
@overrideWidgetbuild(BuildContext context) {
returnLifecycleWrapper(
onLifecycleEvent: (event) {
print(event);
},
child:Scaffold(),
);
}
}
// DialogshowDialog(
context: context,
routeSettings:RouteSettings(name:'dialog'),
builder: (context) {
returnLifecycleWrapper(
onLifecycleEvent: (event) {
print(event);
},
child:Dialog(),
);
},
);- PageView/TabBarView
import'package:flutter/material.dart';
import'package:lifecycle/lifecycle.dart';
classMyPageViewextendsStatefulWidget {
MyPageView({Key key}) :super(key: key);
_MyPageViewStatecreateState() =>_MyPageViewState();
}
class_MyPageViewStateextendsState<MyPageView> {
PageController _pageController;
@overridevoidinitState() {
super.initState();
_pageController =PageController();
}
@overridevoiddispose() {
_pageController.dispose();
super.dispose();
}
@overrideWidgetbuild(BuildContext context) {
returnScaffold(
appBar:AppBar(
title:Text('MyPageView'),
),
// Wrap PageView
body:PageViewLifecycleWrapper(
child:PageView(
controller: _pageController,
children: [
// Wrap child of PageViewChildPageLifecycleWrapper(
index:0,
wantKeepAlive:true,
onLifecycleEvent: (event) {
print('Page@0#${event.name}');
},
child:Container(),
),
ChildPageLifecycleWrapper(
index:1,
wantKeepAlive:true,
onLifecycleEvent: (event) {
print('Page@1#${event.name}');
},
child:Container(),
),
],
),
),
);
}
}
- Nested PageView
import'package:flutter/material.dart';
import'package:lifecycle/lifecycle.dart';
classNestedPageViewextendsStatefulWidget {
NestedPageView({Key key}) :super(key: key);
_NestedPageViewStatecreateState() =>_NestedPageViewState();
}
class_NestedPageViewStateextendsState<NestedPageView> withSingleTickerProviderStateMixin {
PageController _pageController;
TabController _tabController;
finalList<Tab> myTabs =<Tab>[
Tab(text:'left'),
Tab(text:'right'),
];
@overridevoidinitState() {
super.initState();
_pageController =PageController();
_tabController =TabController(vsync:this, length: myTabs.length);
}
@overridevoiddispose() {
_pageController.dispose();
_tabController.dispose();
super.dispose();
}
@overrideWidgetbuild(BuildContext context) {
returnScaffold(
appBar:AppBar(
title:Text('NestedPageView'),
bottom:TabBar(
controller: _tabController,
tabs: myTabs,
),
),
body:PageViewLifecycleWrapper( // Outer PageView
child:TabBarView(
controller: _tabController,
children:<Widget>[
ChildPageLifecycleWrapper(
index:0,
wantKeepAlive:true,
onLifecycleEvent: (event) {
print('OuterPage@0#${event.name}');
},
child:Container(),
),
ChildPageLifecycleWrapper(
index:1,
wantKeepAlive:true,
onLifecycleEvent: (event) {
print('OuterPage@1#${event.name}');
},
child:PageViewLifecycleWrapper( // Inner PageView
child:PageView(
controller: _pageController,
children: [
ChildPageLifecycleWrapper(
index:0,
wantKeepAlive:false,
onLifecycleEvent: (event) {
log.add('InnerPage@0#${event.name}');
},
child:Container(),
),
ChildPageLifecycleWrapper(
index:1,
wantKeepAlive:false,
onLifecycleEvent: (event) {
log.add('InnerPage@1#${event.name}');
},
child:Container(),
),
],
),
),
),
],
),
),
);
}
}
- ListView
@overrideWidgetbuild(BuildContext context) {
returnScaffold(
appBar:AppBar(
title:constText('ListPage'),
),
body:ListView.builder(
itemCount: _data.length,
itemBuilder: (context, index) {
returnScrollViewItemLifecycleWrapper(
onLifecycleEvent: (LifecycleEvent event) {
print('ListPage(item$index)#${event.name}');
},
wantKeepAlive:false,
child:ListTile(
title:Text(
_data[index],
),
),
);
},
),
);
}- Iterates routes.
defaultLifecycleObserver.iterateRoutes(bool Function(route) callback);
- Remove a route.
defaultLifecycleObserver.removeRoute<T>(Route route, [T? result]);
- Dispose a LifecycleObserver when it will never be used.
defaultLifecycleObserver.dispose();