Flutter-StatefulWidget和StatelessWidget

本文详细探讨了Flutter中StatefulWidget和StatelessWidget的区别,强调了StatefulWidget的动态化代价和界面更新机制。建议在开发中优先使用StatelessWidget,避免在根布局和大量子Widget中使用StatefulWidget,尽量将StatefulWidget放在叶子节点,并优化重建过程,减少不必要的重绘。同时,文章指出,虽然StatefulWidget可能导致性能开销,但Flutter提供了三棵树的机制来缓解这个问题。
摘要由CSDN通过智能技术生成

对于万物皆Widget的Fultter,同样的事情一般都有多种控件可以实现,太多的选择总是会让人陷入或多或少的选择纠结症和对性能的忧虑上。

初次接触Flutter,首先必然要面对的两座大山:StatelessWidget & StatefulWidget。 而在这两个控件的选择上,大部分人给出的解释就是:"就像他们的名字一样,无状态静态的视图展示使用StatelessWidget,而有交互,需要动态变化的使用StatefulWidget."

这样的解释正确,但过于模糊,似乎StatelessWidget出现的地方均可以用StatefulWidget来代替,于是为了后期可能的变化、为了coding简便,StatefulWidget被滥用变成了很容易发生的事情。

所以今天我们就详细聊一下StatefulWidget和StatelessWidget的区别和使用。

StatefulWidget与StatelessWidget区别

对于普遍存在的模糊解释,想吐槽又不能说它是错的,但它确实产生了一些无解。

我个人对StatefulWidget与StatelessWidget理解:

StatelessWidget初始化之后就无法改变,如果想改变,那便需要重新创建,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、Customer

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值