简体   繁体   English

从另一个小部件调用小部件的方法

[英]Call method of a widget from another widget

I just started flutter, this is a basic question but I am not able to solve. 我刚刚开始颤抖,这是一个基本问题,但我无法解决。 I created a stateful widget and I need to call the setState() method on click of a button. 我创建了一个有状态小部件,我需要在单击按钮时调用setState()方法。 The button is not part of this stateful widget. 该按钮不是此有状态小部件的一部分。 The button is present in the footer of application. 该按钮位于应用程序的页脚中。

complete application code: 完整的应用代码:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  build(BuildContext context) {
    return new MaterialApp(
        title: "My app title",
        home: new Scaffold(
          appBar: new AppBar(
            title: new Text("My App"),
            backgroundColor: Colors.amber,
          ),
          body: new Container(
            child: new Center(
              child: new MyStateFullWidget(),
            ),
          ),
          persistentFooterButtons: <Widget>[
            new FlatButton(
              onPressed: () {
                // I need to call the update() of MyStateFullWidget/MyStateFullWidgetState class
              },
              child: new Text("Click Here"),
              color: Colors.amber,
              textColor: Colors.white,
            ),
          ],
        ));
  }
}

class MyStateFullWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new MyStateFullWidgetState();
  }
}

class MyStateFullWidgetState extends State<MyStateFullWidget> {
  int count = 0;

  @override
  Widget build(BuildContext context) {
    return new Text("Count: $count");
  }

  update() {
    setState() {
      count++;
    }
  }
}

I need to call the setState() method on click of a button 我需要在单击按钮时调用setState()方法

You may have a few options (or alternatives) to achieve the end result (all with different tradeoffs): 您可能有一些选项(或替代方案)来实现最终结果(所有这些都有不同的权衡):

  • Elevate the state (ie count ) to an Inherited Widget above the Button and Display Widget. 将状态(即count )提升为Button和Display Widget上方的Inherited Widget。 This may be the easiest or most appropriate. 这可能是最简单或最合适的。
  • Leverage some kind of Action-based communication such as Flutter Redux (where you dispatch an action, which affects the display widget via a StoreConnector and rebuilds). 利用某种基于动作的通信,例如Flutter Redux (您dispatch动作,通过StoreConnector影响显示小部件并重建)。 This can be seen as just another way to 'elevate' state. 这可以被视为“提升”状态的另一种方式。 However, this requires a whole new dependency and a lot of overhead given your simple example, but I wanted to point it out. 但是,这需要一个全新的依赖项和大量的开销给出你的简单示例,但我想指出它。
  • You can create some kind of Stream and StreamController that the Display widget subscribes/listens to. 您可以创建Display小部件订阅/侦听的某种StreamStreamController However, this may be overkill and I'm not sure how appropriate representing button clicks over a stream would be. 但是,这可能有点过分,我不确定在流上表示按钮点击的适当程度。

There may be other solutions that I'm not thinking of; 可能还有其他解决方案,我没有想到; however, remember that the goal of reactive UI is to keep state simple . 但请记住,反应式UI的目标是保持状态简单

So if you have multiple leaf widgets that care about a piece of state (want to know it, want to change it), it might mean that this belongs to a higher level component (eg a App-level piece of state, or maybe some other common ancestor - but both could use Inherited Widget to prevent passing the piece of state all around) 因此,如果你有多个关注状态的叶子小部件(想知道它,想要改变它),这可能意味着它属于更高级别的组件(例如,应用程序级别的状态,或者可能是某些其他常见的祖先 - 但两者都可以使用Inherited Widget来阻止所有状态的传递

You should use your Scaffold in the State instead of using in StatelessWidget . 您应该在State中使用Scaffold ,而不是在StatelessWidget中使用。 Here is the working solution. 这是工作解决方案。

class MyApp extends StatelessWidget {
  @override
  build(BuildContext context) {
    return MaterialApp(
        title: "My app title",
        home: MyStateFullWidget());
  }
}

class MyStateFullWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return MyStateFullWidgetState();
  }
}

class MyStateFullWidgetState extends State<MyStateFullWidget> {
  int count = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("My App"),
        backgroundColor: Colors.amber,
      ),
      body: Container(
        child: Center(
          child:Text("Count: $count"),
        ),
      ),
      persistentFooterButtons: <Widget>[
        FlatButton(
          onPressed: update,
          child: Text("Click Here"),
          color: Colors.amber,
          textColor: Colors.white,
        ),
      ],
    );
  }

  void update() {
    setState(() {
      count++;
    });
  }
}

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

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