【Flutter 面试题】什么是Widget,Stateful Widget和Stateless Widget之间的区别?

写在前面

🙋 关于我 ,小雨青年 👉 CSDN博客专家,GitChat专栏作者,阿里云社区专家博主,51CTO专家博主。2023博客之星TOP153。

👏🏻 正在学 Flutter 的同学,你好!

😊 Flutter 面试宝典是解决 Flutter 面试过程中可能出现的问题,而进行汇总整理的。一个问题一篇文章,优化答案,更适合面试过程中的口述满足实际面试需求

🔍 想解决开发中的高频零散问题?碎片化教程 👉 Flutter Tips

🔍 想深入学习 Flutter?系统化教程 👉 Flutter 从0到1 基础入门到应用上线全攻略 & 专栏指引

👥 快来和我们一起交流!👉 讨论群在这里,和大家一起进步!

【Flutter 面试题】什么是Widget,Stateful Widget和Stateless Widget之间的区别?-LMLPHP

解答

Flutter 中,构建界面的核心概念是 WidgetWidgets 是构建应用界面的基本组件,可以理解为用户界面的构建块。每个 Widget 都承担着在屏幕上绘制界面元素的角色,包括布局、颜色和交互等。

在 Flutter 的 Widget 体系中,存在两种主要类型的 Widgets:StatelessWidgetStatefulWidget

StatelessWidget 是一种不保持状态的 Widget。它描述了一种在给定的配置和环境下一成不变的界面。例如,一个图标、一段文本或一个按钮,这些都可能是 StatelessWidget 的例子。这些 Widget 本质上是不可变的,一旦它们被构建,它们的属性就不能再改变

相对地,StatefulWidget 允许您构建一个可以随时间发展和响应用户输入变化的 Widget。StatefulWidget 拥有一个 State 对象,用于存储其状态。当 Widget 的状态需要更新时,可以通过调用 setState() 方法来实现,这将触发框架重建 Widget,从而反映状态的更新。这使得 StatefulWidget 非常适合于那些需要动态变化的 UI 元素,比如计时器、表单以及具有复杂交互的页面等。

理解 StatelessWidget 和 StatefulWidget 之间的差异是至关重要的,因为它们决定了 Widget 如何渲染和重建。简而言之,如果你的 Widget 在整个生命周期内不需要改变其状态,那么使用 StatelessWidget;如果你的 Widget 需要根据用户交互或其他因素更改其外观或行为,那么使用 StatefulWidget。

补充说明

以下是两个示例,分别展示了如何使用 StatelessWidgetStatefulWidget 在 Flutter 中创建基本的用户界面。

StatelessWidget 示例

这个示例展示了一个简单的 StatelessWidget,它显示了一个文本消息。由于它是无状态的,所以这个 Widget 不会随时间改变。

import 'package:flutter/material.dart';

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

// 应用的根 Widget
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Stateless Widget 示例'),
        ),
        body: Center(
          // 自定义的 Stateless Widget
          child: MessageDisplay(),
        ),
      ),
    );
  }
}

// 一个简单的 Stateless Widget,显示固定文本
class MessageDisplay extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text(
      'Hello, Flutter!',
      style: TextStyle(fontSize: 24),
    );
  }
}

运行结果如下

【Flutter 面试题】什么是Widget,Stateful Widget和Stateless Widget之间的区别?-LMLPHP

StatefulWidget 示例

当然,这里有一个不同的 StatefulWidget 示例。这次我们将创建一个简单的计时器应用,当用户按下一个按钮时,计时器开始倒计时。这个例子展示了 StatefulWidget 如何用来响应用户的交互并更新界面。

import 'package:flutter/material.dart';
import 'dart:async';

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

// 应用的根 Widget
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('StatefulWidget 计时器示例 By 小雨青年 CSDN'),
        ),
        body: Center(
          // 自定义的 Stateful Widget 计时器
          child: TimerWidget(),
        ),
      ),
    );
  }
}

// 自定义的 Stateful Widget
class TimerWidget extends StatefulWidget {
  @override
  _TimerWidgetState createState() => _TimerWidgetState();
}

// TimerWidget 的状态
class _TimerWidgetState extends State<TimerWidget> {
  int _seconds = 10; // 倒计时的秒数
  Timer? _timer; // 用于控制倒计时的计时器

  void _startTimer() {
    _seconds = 10; // 重置计时时间
    if (_timer != null) {
      _timer!.cancel(); // 如果计时器已经存在,先取消当前计时器
    }
    // 创建一个新的计时器
    _timer = Timer.periodic(Duration(seconds: 1), (timer) {
      if (_seconds > 0) {
        setState(() {
          _seconds--; // 每秒钟减少秒数
        });
      } else {
        _timer!.cancel(); // 时间到达后取消计时器
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text(
          '倒计时: $_seconds 秒',
          style: TextStyle(fontSize: 24),
        ),
        ElevatedButton(
          onPressed: _startTimer,
          child: Text('开始倒计时'),
        ),
      ],
    );
  }

  @override
  void dispose() {
    _timer?.cancel(); // 释放计时器资源
    super.dispose();
  }
}

运行结果如下

【Flutter 面试题】什么是Widget,Stateful Widget和Stateless Widget之间的区别?-LMLPHP

在这个例子中,我们定义了一个 _TimerWidgetState 类来管理计时器的状态,包括剩余秒数和计时器对象。_startTimer 方法用来初始化或重置计时器,并在每秒减少 _seconds 变量的值。当倒计时完成时,计时器会自动停止。这个例子展示了如何在 StatefulWidget 中处理时间相关的逻辑,并根据时间变化更新 UI。

03-11 17:58