【问题标题】:setState() within StatefulWidget not working properlyStatefulWidget 中的 setState() 无法正常工作
【发布时间】:2019-10-20 19:35:43
【问题描述】:

我想做的是,在单击按钮时更改RawMaterialButton 的颜色。阅读StatefulWidget,它似乎应该可以工作,但由于某种原因它没有。

flutter: Another exception was thrown: setState() called in constructor: ButtonTest#1a93b(lifecycle state: created, no widget, not mounted)

ButtonTest 类:

class ButtonState extends StatefulWidget {
  @override
  State createState() => ButtonTest();
}

class ButtonTest extends State<ButtonState> implements Cipher {
  @override
  String icon = '';

  @override
  String title = '';

  bool enabled = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(this.title),
      ),
      body: RawMaterialButton(
          shape: CircleBorder(side: BorderSide(color: Colors.black)),
          fillColor: enabled ? Colors.blue : Colors.red,
          onPressed: () {
            setState(() {
              this.enabled = true;
            });
          },
          padding: EdgeInsets.all(0)),
    );
  }
}

密码类:

abstract class Cipher {
  String icon;
  String title;
  Widget build(BuildContext context);
}

getCiphers()

getCiphers() {
  final List<Cipher> ciphers = new List();

  ciphers.add(ButtonTest());
  return ciphers;
}

主类:

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

class CipherTools extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'CipherTools',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: CipherScreen(
        ciphers: getCiphers(),
      ),
    );
  }
}

class CipherScreen extends StatelessWidget {
  final List<Cipher> ciphers;

  CipherScreen({Key key, @required this.ciphers}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Ciphers'),
      ),
      body: ListView.builder(
        itemCount: ciphers.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(ciphers[index].title),
            // When a user taps on the ListTile, navigate to the DetailScreen.
            // Notice that we're not only creating a DetailScreen, we're
            // also passing the current todo through to it!
            onTap: () {
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => DetailScreen(cipher: ciphers[index]),
                ),
              );
            },
          );
        },
      ),
    );
  }
}

class DetailScreen extends StatelessWidget {
  // Declare a field that holds the Todo
  final Cipher cipher;

  // In the constructor, require a Todo
  DetailScreen({Key key, @required this.cipher}) : super(key: key);

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

我在这里做错了什么?

【问题讨论】:

    标签: flutter dart statefulwidget


    【解决方案1】:

    像这样包装 setState()。

     if(this.mounted) {
          setState(() {
              this.enabled = true;
            });
     }
    

    【讨论】:

    【解决方案2】:

    有几点:

    • ButtonState 应该被称为 ButtonTest 因为这是 StatefulWidget
    • ButtonTest 应称为 ButtonTestState,因为这是 State

    然后在DetailScreen 中,在build() 方法中,您可以返回StatefulWidget (ButtonTest),如下所示:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-01
      • 2019-08-29
      • 2021-07-28
      • 2020-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多