flutter源码分析——渲染树的生成与更新

提出问题

写这篇文章是因为看见了别人写的这一篇文章:https://blog.csdn.net/jike_yangyujing/article/details/103143425?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-7&spm=1001.2101.3001.4242,这篇文章主要讲解了各种Key的使用方法,其中有个例子我非常感兴趣,想要一探究竟。

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.yellow,
      ),
      home: Screen(),
      showPerformanceOverlay: true,
    );
  }
}

class Screen extends StatefulWidget {
  @override
  _ScreenState createState() => _ScreenState();
}

class _ScreenState extends State<Screen> {
  List<Widget> widgets = [
    //情形1:stateless
    StatelessContainer(),
    StatelessContainer(),
//    //情形2:stateful
//    StatefulContainer(),
//    StatefulContainer(),
//    //情形3:stateful+key
//    StatefulContainer(key: ValueKey(Random().nextInt(1000)),),
//    StatefulContainer(key: ValueKey(Random().nextInt(1000)),),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: widgets,
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: switchWidget,
        child: Icon(Icons.undo),
      ),
    );
  }

  switchWidget() {
    setState(() {
      widgets.insert(0, widgets.removeAt(1));
    });
  }
}

//stateless
class StatelessContainer extends StatelessWidget {
  final Color randomCol = RandomColor().randomColor();

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 100,
      height: 100,
      color: randomCol,
    );
  }
}

//stateful
class StatefulContainer extends StatefulWidget {
  StatefulContainer({Key key}) : super(key: key);

  @override
  _StatefulContainerState createState() => _StatefulContainerState();
}

class _StatefulContainerState extends State<StatefulContainer> {
  final Color randomCol = RandomColor().randomColor();

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 100,
      height: 100,
      color: randomCol,
    );
  }
}

这段代码主要是一个StatefulWidget——Screen,它的子控件主要是一个Row,Row的Children是StatelessContainer /StatefulContainer,而StatelessContainer /StatefulContainer的子控件是一个随机颜色的Container 。点击按钮,预计效果是两个颜色块位置互换。

根据Row的两个Child是StatelessWidget,StatefulWidget,带有Key的StatefulWidget,结果分为三种情形:

1.StatelessWidget:交换成功。

2.StatefulWidget:交换不成功,界面无变化。

3.StatefulWidget+Key:交换成功。

为什么会不一样呢,原文已经给出了解答。本文按照这三种情况,分别对这三个过程进行源码分析。

Element树和RenderObject树的生成

(三种情况是一样的)

void runApp(Widget app) {
  WidgetsFlutterBinding.ensureInitialized()
    ..scheduleAttachRootWidget(app)
    ..scheduleWarmUpFrame();
}

  void scheduleAttachRootWidget(Widget rootWidget) {
    Timer.run(() {
      attachRootWidget(rootWidget);
    });
  }

  void attachRootWidget(Widget rootWidget) {
    _readyToProduceFrames = true;
    _renderViewElement = Re
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值