【问题标题】:Flutter: Widget State: Is this code safe?Flutter:小部件状态:这段代码安全吗?
【发布时间】:2019-10-16 09:39:08
【问题描述】:

下面的代码是一个例子来说明这个问题。下面的代码有效,但是下面的行:

class WidgetCustom extends StatefulWidget {

在 vsCode 中有绿色下划线的“WidgetCustom”,当光标放在它上面时,它会显示消息: “这个类(或这个类继承自的一个类)被标记为@immutable,但它的一个或多个实例字段不是最终的”。

代码运行良好。

使用此代码安全吗?

有没有办法在没有警告的情况下实现这一点?

import 'package:flutter/material.dart';

class WidgetCustom extends StatefulWidget {

  _WidgetCustomState _state;

  WidgetCustom({@required int iCount}) {
    _state = _WidgetCustomState(iCount);
  }

  @override
  State<StatefulWidget> createState() {
    return _state;
  }

  int get getIcount => _state.iCount;
}

class _WidgetCustomState extends State<WidgetCustom> {
  int iCount;

  _WidgetCustomState(this.iCount);

  @override
  Widget build(BuildContext context) {
    return Container(
        child: Row(children: <Widget>[
      Column(
        children: <Widget>[
          RaisedButton(
              child: const Text("Please tap me"),
              onPressed: () {
                setState(() => iCount = iCount + 1);
              }),
          SizedBox(height: 40),
          Text("Tapped $iCount Times")
        ],
      ),
    ]));
  }
}

编辑添加 main.dart

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Custom Widget Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  WidgetCustom _widgetCustom;
  String _sMessage = "Fab has not been pressed";
  @override
  void initState() {
    super.initState();
    _widgetCustom = WidgetCustom(iCount: 99);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Column(children: [
        _widgetCustom,
        SizedBox(height: 40),
        Text(_sMessage),
      ]),
      floatingActionButton: FloatingActionButton(
        onPressed: _fabPressed,
        tooltip: 'Get Value',
        child: Icon(Icons.add),
      ),
    );
  }

  _fabPressed() {
    setState(() => _sMessage =
        "Value from last button click = ${_widgetCustom.getIcount}");
  }
}

【问题讨论】:

  • 是的,我贴的代码是直接复制的。
  • 您需要将 iCount 声明为类级别变量的最终变量。
  • 我需要 iCount 的当前更新值。

标签: flutter widget state


【解决方案1】:

在创建小部件时将初始值作为最终值传递给构造函数,然后从State类中获取。

【讨论】:

    【解决方案2】:

    更新代码:

    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData.dark(),
          home: MyHomePage(title: 'Custom Widget Demo'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      WidgetCustom _widgetCustom;
      String _sMessage = "Fab has not been pressed";
      int _value = 99;
    
      @override
      void initState() {
        super.initState();
        _widgetCustom = WidgetCustom(iCount: _value, function: _update);
      }
    
      void _update(int value) {
        setState(() {
          _value = value;
          _widgetCustom = WidgetCustom(iCount: _value, function: _update);
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text(widget.title)),
          body: Column(
            children: [
              _widgetCustom,
              SizedBox(height: 40),
              Text(_sMessage),
            ],
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: _fabPressed,
            tooltip: 'Get Value',
            child: Icon(Icons.add),
          ),
        );
      }
    
      _fabPressed() {
        setState(() => _sMessage = "Value from last button click = ${_value}");
      }
    }
    
    class WidgetCustom extends StatefulWidget {
      final int iCount;
      final Function function;
    
      WidgetCustom({@required this.iCount, this.function});
    
      @override
      State<StatefulWidget> createState() {
        return _WidgetCustomState();
      }
    }
    
    class _WidgetCustomState extends State<WidgetCustom> {
      int _iCount;
    
      @override
      void initState() {
        super.initState();
        _iCount = widget.iCount;
      }
    
      @override
      Widget build(BuildContext context) {
        return Container(
          child: Row(
            children: <Widget>[
              Column(
                children: <Widget>[
                  RaisedButton(child: const Text("Please tap me"), onPressed: (){
                    _iCount = _iCount + 1;
                    widget.function(_iCount);
                  }),
                  SizedBox(height: 40),
                  Text("Tapped $_iCount Times")
                ],
              ),
            ],
          ),
        );
      }
    }
    

    【讨论】:

    • 关键部分是“int getIcount => _state.iCount;”我需要能够获得价值。
    • 你可以做int get getIcount =&gt; iCount;
    • 我添加了 main.dart 以便更好地说明。
    • @BrianOh 您正在寻找结合@CopsOnRoad 方法的didUpdateWidget 生命周期。
    • @BrianOh 我昨天没时间,反正我刚刚更新了代码,它正在工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-29
    • 2013-02-20
    • 1970-01-01
    • 2023-04-10
    • 2011-05-18
    相关资源
    最近更新 更多