如何通过引用状态小部件传递数据?我想在有状态的小部件内更改变量并更新原始变量

时间:2019-07-18 15:34:53

标签: flutter dart pass-by-reference stateful

我想将数据传递给有状态的小部件,更改小部件内的数据,并在原始位置进行更新。

我想避免使用全局变量,我想知道是否可以通过引用将变量传递给有状态的小部件。

这是一些示例代码,其中数据被传递到小部件。如果使用滑块,则计数器只会在小部件内部更新,而不会在主布局树中更新。

感谢您的帮助。

import 'package:flutter/material.dart';
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @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}) : super(key: key);
  final String title;

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

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

  void _incrementCounter() {
    setState(() {
      _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(
              'Counter inside main layout tree: $_counter',
              style: Theme.of(context).textTheme.title,
            ),
            TestWidget(_counter),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

class TestWidget extends StatefulWidget {
  int counter;
  TestWidget(this.counter);
  @override
  _TestWidgetState createState() => _TestWidgetState();
}

class _TestWidgetState extends State<TestWidget> {
  @override
  Widget build(BuildContext context) {
    return Card(
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.all(Radius.circular(10)),
          side: BorderSide(color: Colors.orange),
        ),
        child: Column(children: <Widget>[
          Text("This card is an external Widget"),
          Slider(
            min: 0,
            max: 100,
            divisions: 101,
            onChanged: (double val) {
              setState(() {
                widget.counter = val.toInt();
              });
            },
            value: widget.counter.toDouble(),
          ),
          Text("Counter inside external widget: ${widget.counter}",
              style: Theme.of(context).textTheme.title),
        ]));
  }
}    

1 个答案:

答案 0 :(得分:1)

实际上StatefulWidget是不可变的,其状态由State类维护。您不能通过引用传递值并更新小部件。相反,您可以只传递值和一个更新值的函数。

示例:

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

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

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

  void _incrementCounter([int value]) {
    setState(() {
      _counter = value ?? (_counter + 1);
    });
  }

  @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(
              'Counter inside main layout tree: $_counter',
              style: Theme.of(context).textTheme.title,
            ),
            TestWidget(
              counter: _counter,
              updateCount: _incrementCounter,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

class TestWidget extends StatelessWidget {
  final int counter;
  final ValueChanged<int> updateCount;

  const TestWidget({Key key, this.counter, this.updateCount}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Card(
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.all(Radius.circular(10)),
        side: BorderSide(color: Colors.orange),
      ),
      child: Column(
        children: <Widget>[
          Text("This card is an external Widget"),
          Slider(
            min: 0,
            max: 100,
            divisions: 101,
            onChanged: (double val) {
              updateCount(val.toInt());
            },
            value: counter.toDouble(),
          ),
          Text(
            "Counter inside external widget: $counter",
            style: Theme.of(context).textTheme.title,
          ),
        ],
      ),
    );
  }
}

可以帮忙的人!