繁体   English   中英

在颤动中强制重建有状态的子小部件

[英]Force rebuild of a stateful child widget in flutter

假设我有一个主屏幕(有状态小部件),其中有一个变量count作为状态。 在这个主屏幕中有一个按钮和另一个有状态的小部件(让我们称之为MyListWidget initState根据count变量的值在MyListWidget中初始化它自己的小部件。显然,如果你改变count的值并调用SetState ,什么都不会发生在MyListWidget因为它在initState中创建值。如何强制重建MyListWidget ?我知道在这个例子中,我们可以在build方法中移动我们在initState中所做的事情。但在我真正的问题中,我不能移动我在build方法中的initState中所做的事情。

这是完整的代码示例:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key}) : super(key: key);

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

class _MyHomePageState extends State<MyHomePage> {
  int count = 5;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Row(
      children: [
        Expanded(
          child: MaterialButton(
            child: Text('Click me'),
            color: Colors.red,
            onPressed: () {
              setState(() {
                count++;
              });
            },
          ),
        ),
        MyListWidget(count),
      ],
    ));
  }
}

class MyListWidget extends StatefulWidget {
  final int count;

  const MyListWidget(this.count, {Key? key}) : super(key: key);

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

class _MyListWidgetState extends State<MyListWidget> {
  late List<int> displayList;

  @override
  void initState() {
    super.initState();
    displayList = List.generate(widget.count, (int index) => index);
  }

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: ListView.builder(
        itemBuilder: (BuildContext context, int index) => ListTile(
          title: Text(displayList[index].toString()),
        ),
        itemCount: displayList.length,
      ),
    );
  }
}

用这个:

class _MyHomePageState extends State<MyHomePage> {
  int count = 5;
  MyListWidget myListWidget = MyListWidget(5);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Row(
      children: [
        Expanded(
          child: MaterialButton(
            child: Text('Click me'),
            color: Colors.red,
            onPressed: () {
              setState(() {
                 count++;
                 myListWidget = MyListWidget(count);
               });
            },
          ),
        ),
        myListWidget,
      ],
    ));
  }
}

我不认为接受的答案是准确的,Flutter 会保留MyListWidget的状态,因为它与之前的类型相同并且在小部件树中的位置相同。

相反,通过更改它的 key来强制重建一个小部件:

class _MyHomePageState extends State<MyHomePage> {
  int count = 5;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Row(
      children: [
        Expanded(
          child: MaterialButton(
            child: Text('Click me'),
            color: Colors.red,
            onPressed: () {
              setState(() {
                count++;
              });
            },
          ),
        ),
        MyListWidget(count, key: ValueKey(count)),
      ],
    ));
  }
}

在此示例中使用ValueKey意味着只有在count实际上不同时才会重新创建状态。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM