±à¼ÍƼö: |
±¾ÎÄÖ÷ÒªÏêϸÁÄÒ»ÏÂStatefulWidgetºÍStatelessWidgetµÄÇø±ðºÍʹÓã¬Ï£ÍûÄܶÔÄúÓÐËù°ïÖú¡£
±¾ÎÄÀ´×ÔÓÚ±©´òСŮº¢-Blog£¬ÓÉ»ðÁú¹ûÈí¼þAlice±à¼¡¢ÍƼö¡£ |
|
ǰÑÔ
¶ÔÓÚÍòÎï½ÔWidgetµÄFultter£¬Í¬ÑùµÄÊÂÇéÒ»°ã¶¼ÓжàÖֿؼþ¿ÉÒÔʵÏÖ£¬Ì«¶àµÄÑ¡Ôñ×ÜÊÇ»áÈÃÈËÏÝÈë»ò¶à»òÉÙµÄÑ¡Ôñ¾À½áÖ¢ºÍ¶ÔÐÔÄܵÄÓÇÂÇÉÏ¡£
³õ´Î½Ó´¥Flutter£¬Ê×ÏȱØÈ»ÒªÃæ¶ÔµÄÁ½×ù´óɽ£ºStatelessWidget & StatefulWidget¡£
¶øÔÚÕâÁ½¸ö¿Ø¼þµÄÑ¡ÔñÉÏ£¬´ó²¿·ÖÈ˸ø³öµÄ½âÊ;ÍÊÇ£º¡°¾ÍÏñËûÃǵÄÃû×ÖÒ»Ñù£¬ÎÞ״̬¾²Ì¬µÄÊÓͼչʾʹÓÃStatelessWidget£¬¶øÓн»»¥,ÐèÒª¶¯Ì¬±ä»¯µÄʹÓÃStatefulWidget.¡±
ÕâÑùµÄ½âÊÍÕýÈ·£¬µ«¹ýÓÚÄ£ºý£¬ËƺõStatelessWidget³öÏֵĵط½¾ù¿ÉÒÔÓÃStatefulWidgetÀ´´úÌæ£¬ÓÚÊÇΪÁ˺óÆÚ¿ÉÄܵı仯¡¢ÎªÁËcoding¼ò±ã£¬StatefulWidget±»ÀÄÓñä³ÉÁ˺ÜÈÝÒ×·¢ÉúµÄÊÂÇé¡£
ËùÒÔ½ñÌìÎÒÃǾÍÏêϸÁÄÒ»ÏÂStatefulWidgetºÍStatelessWidgetµÄÇø±ðºÍʹÓá£
StatefulWidgetÓëStatelessWidgetÇø±ð
¶ÔÓÚÆÕ±é´æÔÚµÄÄ£ºý½âÊÍ£¬ÏëͲÛÓÖ²»ÄÜ˵ËüÊÇ´íµÄ£¬µ«Ëüȷʵ²úÉúÁËһЩÎ޽⡣
ÎÒ¸öÈ˶ÔStatefulWidgetÓëStatelessWidgetÀí½â£º
StatelessWidget³õʼ»¯Ö®ºó¾ÍÎÞ·¨¸Ä±ä£¬Èç¹ûÏë¸Ä±ä£¬ÄDZãÐèÒªÖØÐ´´½¨£¬newÁíÒ»¸öStatelessWidget½øÐÐÌæ»»¡£µ«StatelessWidgetÒòΪÊǾ²Ì¬µÄ£¬ËûûÓÐ°ì·¨ÖØÐ´´½¨×Ô¼º¡£ËùÒÔStatefulWidget±ãÌṩÁËÕâÑùµÄ»úÖÆ£¬Í¨¹ýµ÷ÓÃsetState((){})±ê¼Ç×ÔÉíΪdirty״̬£¬ÒԵȴýÏÂÒ»´ÎϵͳµÄÖØ»æ¼ì²é¡£
StatefulWidget ¶¯Ì¬»¯´ú¼Û
ͨ¹ý¶¨Ò壬StatefulWidgetÔõô¿´¶¼ÊÇÒ»¸öÍò½ðÓ͵ĴæÔÚ£¬µ«ÊÇ£¬ÎÒÆÚÍûÄãÄܶÔStatefulWidget¶¯Ì¬»¯Ëù¸¶³öµÄ´ú¼ÛÓÐËùÁ˽⣺
ÔÚStateÀàÖеĵ÷ÓÃsetState((){})¸üÐÂÊÓͼ£¬½«»á´¥·¢State.build£¡ Ò²½«¼ä½ÓµÄ´¥·¢Æäÿ¸ö×ÓWidgetµÄ¹¹Ôì·½·¨ÒÔ¼°build·½·¨¡£
ÕâÒâζÕâÊ²Ã´ÄØ£¿ Èç¹ûÄãµÄ¸ù²¼¾ÖÊÇÒ»¸öStatefulWidget£¬ÄÇôÿÔÚ¸ùStateÖе÷ÓÃÒ»´ÎsetState((){})£¬¶¼½«ÊÇÒ»´ÎÕûÒ³ËùÓÐWidgetµÄrebuild£¡£¡£¡
¾Ù¸öÀõ×Ó£º
class MyStatefulWidget extends StatefulWidget
{
@override
State<StatefulWidget> createState() {
return CustomerState();
}
}
class CustomerState extends State<MyStatefulWidget>
{
int _num = 0; @override
Widget build(BuildContext context) {
// TODO: implement build
return Row(children: <Widget>[
GestureDetector(
onTap: () {
setState(() {
_num++;
});
},
child: Text("Click My"),
),
Text("1:AAAAA"),
Text("2:BBBBB"),
Text("3:C:" + _num.toString()),
CustomerContainer()
]);
}
} class CustomerContainer extends StatelessWidget
{
@override
Widget build(BuildContext context) {
for (int i = 0; i < 1000000; i++) {
print("ÎÒÊÇÒ»¸öºÄʱ²Ù×÷ for:" + i.toString());
}
return Container(
child: Text("4:DDDD"),
);
}
}
|
¶ÔÓÚÉÏÃæµÄ´úÂ룬ÿһ´Îµã»÷ ¡±My Click¡°£¬CustomerState build·½·¨£¬ÒÔ¼°Row¡¢Text¡¢CustomerContainerµÈ×ÓWidget¶¼½«Öؽ¨£¬ÔÝʱ»¹²»Ì«È·¶¨ÔÚ»æÖÆÉÏFlutterÊÇ·ñ»áÓлº´æÓÅ»¯£¬µ«´óÁ¿µÄ¶ÔÏó´´½¨Óë·½·¨Ö´ÐÐÊÇÅܲ»Á˵ġ£Èç¹ûij¸ö×ÓWidgetµÄ¹¹Ôì»òbuild½øÐÐÁ˽ÏΪºÄʱµÄ²Ù×÷£¬ÄǸüÊÇÔÖÄÑ£¡£¡£¡
ËùÒÔ£¬ÄãÒ²Ó¦¸ÃÄÜÀí½âн¨Ò»¸öFlutter¹¤³Ì¸ù²¼¾ÖΪʲôÊÇÒ»¸öStatelessWidgetÁË¡£
StatefulWidgetÊÇÈçºÎʵÏÖ½çÃæ¸üеģ¿
setState(() {
_num++;
}); |
ÔÚ½Ó´¥Ò»ÃÅеļ¼Êõʱ£¬¾É¼¼ÊõËù´øÀ´µÄ¹ßÐÔ˼άÊǺܿÉŵġ£
³õ´Î½Ó´¥ÏñÉÏÃæÕâÑùsetStateµÄ·½·¨Ê±£¬Ï뵱ȻµÄÈÏΪState.setState((){})ʵÏÖÔÀíÓ¦¸ÃÀàËÆÓÚ
Android µÄ DataBinding »òÕß Vue µÄÊý¾Ý½Ù³Ö£¬ÊµÏÖ¹Û²ìÕßģʽ²¢×ö¶¨Ïò¸üУ¬Ö»¾Ö²¿¸üаó¶¨ÁË
_num µÄ Widget¡£
Ò²ÕýÊÇÒòΪ±§×ÅÕâÑùµÄÏë·¨£¬¶ÔÓÚ´óÁ¿Ê¹ÓÃStatefulWidget²¢Ã»ÓÐʲôÐÄÀí¸ºµ£¡£
µ«ÉÏÃæµÄcaseÒѾºÜÖ±°×µÄ¸æËßÎÒÃÇ£¬ÊÂʵ²¢²»ÊÇÕâÑù£¡£¡£¡
ÎÒÃÇÏÈ¿´Ò»ÏÂState.setState((){})Ô´Â룺
@protected
void setState(VoidCallback fn) {
...
_element.markNeedsBuild();
} |
Ê¡ÂÔÁËËùÓеÄassertЧÑ飬ʵ¼ÊÓÐÒâÒåµÄÖ»ÓÐÕâÒ»¾ä£¬±ê¼Ç element ΪÐèÒª build ״̬¡£ÔÙÍùÏ¿´£º
void markNeedsBuild()
{
...
if (dirty)
return;
_dirty = true;
owner.scheduleBuildFor(this);
} |
±ê¼Ç element Ϊ dirty ״̬£¬²¢Ö´ÐÐ owner µÄ scheduleBuildFor
·½·¨¡£owner ÊÇ BuildOwner£¬¿´Ãû×Ö¾ÍÖªµÀÊǸºÔðbuildµÄ¡£
void scheduleBuildFor(Element
element) {
...
if (!_scheduledFlushDirtyElements && onBuildScheduled
!= null) {
_scheduledFlushDirtyElements = true;
onBuildScheduled();
}
...
} |
onBuildScheduled() ÖÐÓÖµ÷ÓÃÁË ensureVisualUpdate() È»ºó scheduleFrame(),Ö±½Ó¿´ÏÂ
scheduleFrame
void scheduleFrame()
{
if (_hasScheduledFrame || !_framesEnabled)
return;
ui.window.scheduleFrame();
_hasScheduledFrame = true;
} |
µ÷ÓÃÁËWindowÀàµÄscheduleFrame()·½·¨£¬scheduleFrame()ÊÇÒ»¸önative·½·¨£¬ÊµÏÖÕæÕýµÄ½çÃæ»æÖÆ£¬µ½ÕâÀïÎÒÃǾͻù±¾Çå³þÎÒÃÇÒªÖªµÀµÄ¶«Î÷ÁË¡£
Flutter²¢Ã»ÓÐʵÏÖÊý¾ÝË«Ïò°ó¶¨£¬ÄãÔÚState.setState((){})ÖÐдʲô´úÂë¶¼²»ÖØÒª£¬Ëü½öÓÃÀ´±ê¼ÇÕâ¸öState¶ÔÏóÐèÒªÖØÐÂBuild£¬ÖØÐÂbuildºó¸ù¾ÝÒѱä¸üµÄÊý¾ÝÀ´´´½¨ÐµÄWidget¡£
setState(() {
_num++;
}); |
ÒÔÕâÁ½ÖÖд·¨¶¼¿ÉÒÔʵÏÖÒÀÀµ_numµÄWidget¸üС£
¿ª·¢ÖÐÈçºÎÑ¡ÔñStatefulWidgetºÍStatelessWidget£¿
ͨ¹ýÉÏÃæÈý¸öС½á£¬ÄãÓ¦¸Ã´óÖÂÁ˽âÁËStatefulWidgetµÄÊÓͼ¸üÐÂÊÇÈçºÎ¼òµ¥´Ö±©¡¢ÇÒ´ú¼Û½Ï¸ß¡£
¶Ô±ÈVue£¨Vueͨ¹ýË«ÏòÊý¾Ý°ó¶¨ÊµÏÖ¾Ö²¿DOM¸üÐÂÒÔÌá¸ßЧÂÊ£©£¬Flutter½«Ô±¾ÓÉ¿ò¼Ü¸ºÔðµÄһЩÐÔÄÜÓÅ»¯×ª¼ÞÔÚÁË¿ª·¢ÕßÉíÉÏ¡£ÓÐÒ»µãÀàËÆÓÚC++ºÍjavaµÄÄÚ´æ»ØÊÕ¡£
¼ÈÈ»·´¿¹²»ÁË£¬¾ÍÌÉÏÂÀ´ÏíÊÜ¡°×ÔÓÉ¡±µÄ¿ì¸Ð°É¡£ÏÂÃæÎÒÃÇÁÄÁÄÈçºÎÔÚ¿ª·¢ÖÐÑ¡ÔñStatefulWidgetºÍStatelessWidgetÀ´Ìá¸ßÊÓͼ¸üÐÂÐÔÄÜ¡£
ÏÈÁÐһЩ¾ö²ßµã£º
ÓÅÏÈʹÓà StatelessWidget
º¬ÓдóÁ¿×Ó Widget£¨Èç¸ù²¼¾Ö¡¢´Î¸ù²¼¾Ö£©É÷Óà StatefulWidget
¾¡Á¿ÔÚÒ¶×Ó½ÚµãʹÓà StatefulWidget
½«»áµ÷Óõ½setState((){}) µÄ´úÂ뾡¿ÉÄܵĺÍÒª¸üеÄÊÓͼ·â×°ÔÚÒ»¸ö¾¡¿ÉÄÜСµÄÄ£¿éÀï¡£
Èç¹ûÒ»¸öWidgetÐèÒªreBuild£¬ÄÇôËüµÄ×ӽڵ㡢Ðֵܽڵ㡢ÐֵܽڵãµÄ×Ó½ÚµãÓ¦¸Ã¾¡¿ÉÄÜÉÙ
ÁíÍâÆäËûÐèҪעÒâµÄµã
Ïà½ÏAndroidµÄView£¬Flutter WidgetµÄ¹¹Ôì·½·¨¿ÉÄܱ»»áÖ´Ðкܶà´Î£¬×öµÄÊÂÇéÓ¦¸Ã¾¡¿ÉÄܵÄÉÙ
Flutter Widget build·½·¨¿ÉÄÜ»áÖ´Ðжà´Î£¬×öµÄÊÂÇéÓ¦¸Ã¾¡¿ÉÄܵÄÉÙ

¼ÙÉèÄãÓÐÈçÉÏÒ»¸öWidgetÊ÷£¬ºìÉ«±íʾµÄÊÇÒ»¸ö½«»á±»¸Ä±äµÄWidget¡£Èç¹û°´ÕÕÕâÑùµÄ²¼¾Ö½á¹¹£¬ÄÇôÿһ´ÎºìÉ«µÄ
leaf ½Úµã·¢Éú±ä»¯²¢Öؽ¨£¬ËüµÄËĸöÐֵܽڵãÒ²»áÖØÐ´´½¨£¬¶ÔÓÚÕâÑùµÄ½á¹¹£¬ÄãÓ¦¸Ã×öÕâÑùµÄÓÅ»¯£º

½«±ä»¯µÄ½ÚµãÏ·ŷâ×°µ½Ò»¸ö¸üСµÄ·ÖÖ§µ±ÖУ¬Ê¹µÃËüµÄÐֵܽڵ㾡¿ÉÄܵÄÉÙ¡£
ÎÒÃÇÓüòµ¥µÄdemoÀ´ËµÃ÷£ºBBBÊǾ²Ì¬Îݸ¡¢Ã¿µã»÷Ò»´ÎClick My, AAAºóÃæµÄÊý×Ö¶¼»á¼Ó1

class CustomerStatefulWidget
extends StatefulWidget {
final String _name;
CustomerStatefulWidget(this._name);
@override
State<StatefulWidget> createState() {
print("TAG, CustomerStatefulWidget:"
+ _name + " build");
return CustomerState("CustomerStateA");
}
} class CustomerState extends State<CustomerStatefulWidget>
{
String _name; CustomerState(this._name) {
print("TAG, CustomerState:" + _name
+ " ¹¹Ôì");
} int _customerStatelessText = 0; @override
Widget build(BuildContext context) {
print("TAG, " + _name + " build");
return Container(
margin: EdgeInsets.only(top: 100),
color: Colors.yellow,
child: Column(
children: <Widget>[
CustomerStatelessWidget("BBB", "BBB"),
CustomerStatelessWidget(
"AAA", "AAA:" + _customerStatelessText.toString()),
GestureDetector(
onTap: () {
print("Click My");
setState(() {
_customerStatelessText++;
});
},
child: Text("Click My"),
)
],
),
);
}
} class CustomerStatelessWidget extends StatelessWidget
{
final String _text;
final String _name; CustomerStatelessWidget(this._name, this._text)
{
print("TAG, CustomerStatelessWidget:"
+ _name + " ¹¹Ôì");
} @override
Widget build(BuildContext context) {
print("TAG, CustomerStatelessWidget:"
+ _name + " build");
if (_name == "BBB") {
// for (int i = 0; i < 10000000; i++) {
// print("for:" + i.toString());
// }
print("ÎÒÊÇÒ»¸öºÄʱ·½·¨£¬ºÄʱ2s");
}
return Text(_text);
}
} |
ÔÚÎÒÃǵã»÷Click MyÖ®ºó£¬¿´Ò»ÏÂÈÕÖ¾£º
I/flutter (31310):
Click My
I/flutter (31310): TAG, CustomerStateA build
I/flutter (31310): TAG, CustomerStatelessWidget:BBB
¹¹Ôì
I/flutter (31310): TAG, CustomerStatelessWidget:AAA
¹¹Ôì
I/flutter (31310): TAG, CustomerStatelessWidget:BBB
build
I/flutter (31310): ÎÒÊÇÒ»¸öºÄʱ·½·¨£¬ºÄʱ2s
I/flutter (31310): TAG, CustomerStatelessWidget:AAA
build
|
Ô±¾¾²Ì¬ÎÞÐèRebuildµÄBBB£¬ÒòΪºÍAAAÊôÓÚÐֵܽڵ㣬ÔÚAAA·¢Éú¸Ä±äʱ±»¶¯Öػ棬¸üÔã¸âµÄÊÇBBB»¹ÓÐÒ»¸ö·Ç³£ºÄʱµÄbuild·½·¨¡£ÄÇôÈçºÎÓÅ»¯ÄØ£¿
½«ClickMyÓëAAA¿Ø¼þ·â×°ÔÚÒ»¸ö¸üСµÄStatefulWidgetµ±ÖУ¬BBBÉÏÌáÖÁStatelessWidget
class WrapStatelessWidget
extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("TAG, WrapStatelessWidget: build");
return Container(
margin: EdgeInsets.only(top: 100),
color: Colors.yellow,
child: Column(
children: <Widget>[
CustomerStatelessWidget("BBB", "BBB"),
CustomerStatefulWidget("AAA")
],
),
);
}
}
class CustomerStatefulWidget extends StatefulWidget
{
final String _name; CustomerStatefulWidget(this._name); @override
State<StatefulWidget> createState() {
print("TAG, CustomerStatefulWidget:"
+ _name + " build");
return CustomerState("CustomerStateA");
}
} class CustomerState extends State<CustomerStatefulWidget>
{
String _name; CustomerState(this._name) {
print("TAG, " + _name + " ¹¹Ôì");
}
int _customerStatelessText = 0; @override
Widget build(BuildContext context) {
print("TAG, CustomerState:" + _name
+ " build");
return Container(
child: Column(
children: <Widget>[
CustomerStatelessWidget(
"AAA", "AAA:" + _customerStatelessText.toString()),
GestureDetector(
onTap: () {
print("Click My");
_customerStatelessText++;
setState(() {});
},
child: Text("Click My"),
)
],
),
);
}
} class CustomerStatelessWidget extends StatelessWidget
{
final String _text;
final String _name; CustomerStatelessWidget(this._name, this._text)
{
print("TAG, CustomerStatelessWidget:"
+ _name + " ¹¹Ôì");
} @override
Widget build(BuildContext context) {
print("TAG, CustomerStatelessWidget:"
+ _name + " build");
if (_name == "BBB") {
// for (int i = 0; i < 1000000; i++) {
// print("for:" + i.toString());
// }
print("ÎÒÊÇÒ»¸öºÄʱ·½·¨£¬ºÄʱ2s");
}
return Text(_text);
}
|
ÎÒÃÇÔÙµãÒ»ÏÂClickMy¿´ÏÂÈÕÖ¾£º
I/flutter (31310):
Click My
I/flutter (31310): TAG,CustomerStateA build
I/flutter (31310): TAG, CustomerStatelessWidget:AAA
¹¹Ôì
I/flutter (31310): TAG, CustomerStatelessWidget:AAA
build |
AAAµÄÖØ»æ²»»áÔÙʹµÃBBB±»ÆÈÖØ»æ£¡
½áÂÛ
ÖØÉêÒ»ÏÂStatefulWidgetʹÓõľö²ßµã£º
ÓÅÏÈʹÓà StatelessWidget
º¬ÓдóÁ¿×Ó Widget£¨Èç¸ù²¼¾Ö¡¢´Î¸ù²¼¾Ö£©É÷Óà StatefulWidget
¾¡Á¿ÔÚÒ¶×Ó½ÚµãʹÓà StatefulWidget
½«»áµ÷Óõ½setState((){}) µÄ´úÂ뾡¿ÉÄܵĺÍÒª¸üеÄÊÓͼ·â×°ÔÚÒ»¸ö¾¡¿ÉÄÜСµÄÄ£¿éÀï¡£
Èç¹ûÒ»¸öWidgetÐèÒªreBuild£¬ÄÇôËüµÄ×ӽڵ㡢Ðֵܽڵ㡢ÐֵܽڵãµÄ×Ó½ÚµãÓ¦¸Ã¾¡¿ÉÄÜÉÙ
ÁíÍâÆäËûÐèҪעÒâµÄµã
Ïà½ÏAndroidµÄView£¬Flutter WidgetµÄ¹¹Ôì·½·¨¿ÉÄܱ»»áÖ´Ðкܶà´Î£¬×öµÄÊÂÇéÓ¦¸Ã¾¡¿ÉÄܵÄÉÙ
Flutter Widget build·½·¨¿ÉÄÜ»áÖ´Ðжà´Î£¬×öµÄÊÂÇéÓ¦¸Ã¾¡¿ÉÄܵÄÉÙ |