MST

星途 面试题库

面试题:Flutter中StatefulWidget和StatelessWidget的区别及应用场景

请详细阐述Flutter中StatefulWidget和StatelessWidget的区别,并举例说明在哪些实际场景下会分别使用它们。
48.3万 热度难度
前端开发Flutter

知识考点

AI 面试

面试题答案

一键面试

区别

  1. 状态可变与否
    • StatelessWidget:是不可变的,即它的属性在创建后不能被改变。一旦创建,其状态就固定了。
    • StatefulWidget:是可变的,它有一个与之关联的State对象,该对象可以在Widget的生命周期内改变状态。
  2. 更新机制
    • StatelessWidget:当它的父Widget重建时,它才会重建。因为它本身没有可变状态,所以不会因为自身状态改变而重建。
    • StatefulWidget:当与之关联的State对象的状态发生改变时,调用setState方法会触发Widget的重建,从而更新UI。
  3. 生命周期
    • StatelessWidget:只有build方法,用于构建UI。每次父Widget重建时,都会调用它的build方法。
    • StatefulWidget:有多个生命周期方法,如createState用于创建关联的State对象,State对象有initState(在State对象插入到树中时调用一次)、didUpdateWidget(当Widget的配置改变时调用)、dispose(当State对象从树中移除时调用)等。

实际场景举例

  1. StatelessWidget的使用场景
    • 显示静态文本:例如一个标题文本,它在整个应用运行过程中不需要改变。
    class MyTitle extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Text('这是一个静态标题');
      }
    }
    
    • 简单图标展示:一个固定的图标,如应用的logo图标。
    class MyLogo extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Icon(Icons.android);
      }
    }
    
  2. StatefulWidget的使用场景
    • 按钮点击计数:当按钮被点击时,需要更新点击次数的显示。
    class ClickCounter extends StatefulWidget {
      @override
      _ClickCounterState createState() => _ClickCounterState();
    }
    
    class _ClickCounterState extends State<ClickCounter> {
      int count = 0;
      @override
      Widget build(BuildContext context) {
        return Column(
          children: [
            Text('点击次数: $count'),
            ElevatedButton(
              onPressed: () {
                setState(() {
                  count++;
                });
              },
              child: Text('点击我'),
            )
          ],
        );
      }
    }
    
    • 用户输入表单:例如登录表单,用户输入的用户名和密码等状态会改变,需要实时更新UI。
    class LoginForm extends StatefulWidget {
      @override
      _LoginFormState createState() => _LoginFormState();
    }
    
    class _LoginFormState extends State<LoginForm> {
      String username = '';
      String password = '';
      @override
      Widget build(BuildContext context) {
        return Column(
          children: [
            TextField(
              onChanged: (value) {
                setState(() {
                  username = value;
                });
              },
              decoration: InputDecoration(labelText: '用户名'),
            ),
            TextField(
              onChanged: (value) {
                setState(() {
                  password = value;
                });
              },
              decoration: InputDecoration(labelText: '密码'),
              obscureText: true,
            ),
            ElevatedButton(
              onPressed: () {
                // 处理登录逻辑
              },
              child: Text('登录'),
            )
          ],
        );
      }
    }