将变量从有状态小部件传递给状态

时间:2021-04-02 14:40:47

标签: flutter dart

我尝试传递一个变量“int counter = 0;”在状态小部件中,但我不知道为什么我无法检索它,应用程序将我返回为“Null”,但我将所有变量传递给了构造函数,(类 MyHomePage 扩展了 StatefulWidget)。

import 'package:flutter/material.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: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title, this.counter}) : super(key: key);
  final String title;
  int counter= 0;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  void _incrementCounter() {
    setState(() {
      widget.counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '${widget.counter}',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

感谢您的帮助

2 个答案:

答案 0 :(得分:1)

Widgets(包括 StatefulWidgets)应该永远是不可变的,不应该在它们的生命周期中改变。事实上,如果您尝试向 final 添加非 StatefulWidget 变量,您应该会看到警告,因为它是 Widget 的子类型,它具有 @immutable注释。

任何逻辑实际上发生在 StatefulWidget 子类中是非常罕见的。相反,所有状态和相关逻辑都应该在 State 类中。

您应该像这样将 counter 移动到状态类中:

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

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

class _MyHomePageState extends State<MyHomePage> {
  int counter = 0;

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

  // the rest is the same, except using counter instead of widget.counter
}

答案 1 :(得分:0)

先来分析代码


 home: MyHomePage(title: 'Flutter Demo Home Page'),
 // You did not pass integer to the counter field, dart pass null to counter field


class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title, this.counter
/* here null will be initialized to the counter field */
}) : super(key: key);
  final String title;
  int counter= 0; // now it is null
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

因此你得到空值

如何正确传递你的场景:

import 'package:flutter/material.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: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title, this.counter=0}) : super(key: key);
  final String title;
  int counter;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  void _incrementCounter() {
    setState(() {
      widget.counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '${widget.counter}',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}