MST
星途 面试题库

面试题:Flutter中Widget生命周期各阶段的特点及应用场景

请详细阐述Flutter中Widget从创建到销毁的生命周期各个阶段,比如initState、didChangeDependencies、build、dispose等,并且说明在每个阶段通常适合进行哪些操作,例如数据初始化、监听数据变化、构建UI以及释放资源等,并举出相应的简单代码示例。
32.9万 热度难度
前端开发Flutter

知识考点

AI 面试

面试题答案

一键面试

initState

  • 阶段说明:在Widget插入到树中时调用,且只会调用一次。
  • 适合操作:用于数据初始化,如初始化控制器、订阅流等。
  • 代码示例
class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  late int count;

  @override
  void initState() {
    super.initState();
    count = 0;
  }

  @override
  Widget build(BuildContext context) {
    return Text('Count: $count');
  }
}

didChangeDependencies

  • 阶段说明:在initState之后调用,并且当State对象的依赖发生变化时也会调用。
  • 适合操作:用于依赖注入场景,如获取InheritedWidget的数据。
  • 代码示例
class MyInheritedWidget extends InheritedWidget {
  final String data;
  MyInheritedWidget({required this.data, required Widget child}) : super(child: child);

  static MyInheritedWidget of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>()!;
  }

  @override
  bool updateShouldNotify(MyInheritedWidget oldWidget) {
    return data != oldWidget.data;
  }
}

class MyDependentWidget extends StatefulWidget {
  @override
  _MyDependentWidgetState createState() => _MyDependentWidgetState();
}

class _MyDependentWidgetState extends State<MyDependentWidget> {
  late String myData;

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    myData = MyInheritedWidget.of(context).data;
  }

  @override
  Widget build(BuildContext context) {
    return Text('Data from InheritedWidget: $myData');
  }
}

build

  • 阶段说明:每次Widget需要构建UI时调用,当State对象的状态改变(调用setState)时也会触发。
  • 适合操作:构建UI,返回一个Widget树。
  • 代码示例
class CounterWidget extends StatefulWidget {
  @override
  _CounterWidgetState createState() => _CounterWidgetState();
}

class _CounterWidgetState extends State<CounterWidget> {
  int counter = 0;

  void increment() {
    setState(() {
      counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('Counter: $counter'),
        ElevatedButton(onPressed: increment, child: Text('Increment'))
      ],
    );
  }
}

didUpdateWidget

  • 阶段说明:当Widget的配置发生变化时调用,父Widget重建并传递新的Widget实例给子Widget时触发。
  • 适合操作:根据新的配置更新State状态。
  • 代码示例
class ParentWidget extends StatefulWidget {
  int value;
  ParentWidget({required this.value});

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

class _ParentWidgetState extends State<ParentWidget> {
  @override
  Widget build(BuildContext context) {
    return ChildWidget(value: widget.value);
  }
}

class ChildWidget extends StatefulWidget {
  int value;
  ChildWidget({required this.value});

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

class _ChildWidgetState extends State<ChildWidget> {
  late int myValue;

  @override
  void didUpdateWidget(ChildWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.value != oldWidget.value) {
      setState(() {
        myValue = widget.value;
      });
    }
  }

  @override
  void initState() {
    super.initState();
    myValue = widget.value;
  }

  @override
  Widget build(BuildContext context) {
    return Text('Value: $myValue');
  }
}

deactivate

  • 阶段说明:Widget从树中移除时调用,可能是暂时移除,之后还可能重新插入树中。
  • 适合操作:用于暂时停止一些活动,如暂停动画等。
  • 代码示例
class AnimatedWidgetExample extends StatefulWidget {
  @override
  _AnimatedWidgetExampleState createState() => _AnimatedWidgetExampleState();
}

class _AnimatedWidgetExampleState extends State<AnimatedWidgetExample> with SingleTickerProviderStateMixin {
  late AnimationController controller;

  @override
  void initState() {
    super.initState();
    controller = AnimationController(vsync: this, duration: Duration(seconds: 2));
    controller.repeat();
  }

  @override
  void deactivate() {
    controller.stop();
    super.deactivate();
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: controller,
      builder: (context, child) {
        return Transform.rotate(
          angle: controller.value * 2 * 3.14,
          child: child,
        );
      },
      child: Container(
        width: 100,
        height: 100,
        color: Colors.blue,
      ),
    );
  }
}

dispose

  • 阶段说明:Widget从树中永久移除时调用,释放资源,如取消订阅、释放控制器等。
  • 适合操作:释放State对象占用的资源。
  • 代码示例
class StreamWidget extends StatefulWidget {
  @override
  _StreamWidgetState createState() => _StreamWidgetState();
}

class _StreamWidgetState extends State<StreamWidget> {
  late StreamSubscription<int> subscription;

  @override
  void initState() {
    super.initState();
    final stream = Stream.periodic(Duration(seconds: 1), (count) => count);
    subscription = stream.listen((data) {
      setState(() {
        // 更新UI
      });
    });
  }

  @override
  void dispose() {
    subscription.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}