Widget 思维:Flutter 页面为什么是一棵树

理解 Widget 树、Element 树、BuildContext 的关系,知道为什么页面要通过组合搭出来。

Widget声明式 UI

万物皆 Widget 的真正含义

Flutter 中看得见的 Text、Image、Button 是 Widget,看不见的 Padding、Center、Row、Column、Theme 也是 Widget。页面不是一个大模板,而是一棵由很多小 Widget 组成的树。

Widget 不是“界面实例”

Widget 更像一份配置描述,它告诉 Flutter 当前界面应该长什么样。真正负责挂载和生命周期的是 Element,真正绘制的是 RenderObject。初学阶段不用深挖底层,但要记住:build 可以多次执行,所以不要在 build 里做重 IO、发请求或写复杂副作用。

一个简单的组合例子

class ProfileCard extends StatelessWidget {
  const ProfileCard({super.key});

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Row(
          children: const [
            CircleAvatar(child: Text('F')),
            SizedBox(width: 12),
            Text('Flutter Developer'),
          ],
        ),
      ),
    );
  }
}

什么时候拆组件

  • 一段 UI 超过 80 行,可以考虑拆。
  • 同一个卡片、按钮、列表项出现两次以上,应该拆。
  • build 里嵌套太深,阅读困难,也应该拆。
  • 拆组件不是越碎越好,优先按业务含义拆。

官方参考