如何在StatefullWidget中将另一个布尔值更改为另一个? [英] How do i change a boolean in a StatefullWidget from another one?

查看:228
本文介绍了如何在StatefullWidget中将另一个布尔值更改为另一个?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Flutter的新手.

i'm brand new to Flutter.

我正在尝试通过按一个按钮来打开面板,而不是通过按该面板上的按钮来关闭它.

I'm trying to open a panel pressing a button and than closing it by pressing a button on that panel.

我已经设法通过在同一页中编写代码来做到这一点.

I've managed to do it by writing the code in the same page.

我不能做的就是拆分代码并保持一切正常工作.

What i can't do is splitting the code and keep everything working.

我实际上正在做的是在初始化为False的小部件的状态中调用变量,然后使用if语句调用:或者是我想要的空容器或面板.

What I'm actually doing is calling a variable in the State of a widget that is initialized False and then with an if statement i'm calling: or an empty container or the panel i want.

当我按下按钮时,我调用SetState(){},变量变为true以使面板出现,然后面板中有执行相反操作的按钮.

When i press the button i call SetState(){} and the variable changes to true to let the panel appears, then in the panel there's button that do opposite thing.

假设我在做什么,这是正确的.如何在新页面中重构面板的情况下继续执行此操作?

Assuming that what i'm doing it is correct. How to i keep doing this with the panel refactored in a new page?

我对流和继承的小部件做了一些修改,但我还没有完全理解

I've red something about streams and inherited widgets but i haven't completely understood

推荐答案

如果我理解正确,则希望从另一个StatefullWidget通知StatefullWidget.关于此方法有几种方法,但是由于您已经提到Streams,因此我将尝试发布一个示例并对此情况进行一些解释.

If I understand correctly, you want to notify a StatefullWidget from another StatefullWidget. There are several approaches on this one but since you've mentioned Streams, I'll try to post an example and explain a bit this scenario.

因此,基本上,您可以将流视为一端连接到水龙头的管道,而另一端则将其添加到杯子中(该端可以分成多个端并放入多个杯子中,称为广播流")

So basically, you can consider the streams like a pipe linked to a faucet in one end and the other end it's added into a cup (the end can be split in multiple ends and put in multiple cups, "broadcast streams").

现在,杯子是听众(订阅者),它在等待水从管子滴下.

Now, the cup is the listener (subscriber) and waits for water to drop trough the pipe.

水龙头是发射器,当水龙头打开时,它会发出水滴.

The faucet is the emitter, and it will emit water droplets when the faucet is opened.

将水龙头的另一端放入杯中时可以将其打开,这是一种带有一些凉爽传感器的智能水龙头(发射器将在检测到用户"时开始发射事件).

The faucet can be opened when the other end is put into a cup, this is a smart faucet with some cool sensors, (the emitter will start emitting events when a subscriber is "detected).

液滴是应用程序中发生的实际事件.

The droplets are actual events that are happening in the the app.

此外,您还必须记住关闭水龙头,以免杯子漏水到厨房地板上. (完成事件处理后,必须取消订阅者,以免泄漏).

Also you must remember to close the faucet in order to avoid a massive leak from your cup into the kitchen floor. (you must cancel the subscribers when you've done handling events to avoid a leak).

现在针对您的特殊情况,这是说明上述隐喻的代码段:

Now for your particular case here's the code snippet that kind of illustrate the above metaphor:

class ThePannel extends StatefulWidget { // this is the cup
  final Stream<bool> closeMeStream; // this is the pipe 

  const ThePannel({Key key, this.closeMeStream}) : super(key: key);

  @override
  _ThePannelState createState() => _ThePannelState(closeMeStream);
}

class _ThePannelState extends State<ThePannel> {
  bool _closeMe = false;
  final Stream<bool> closeMeStream;
  StreamSubscription _streamSubscription;

  _ThePannelState(this.closeMeStream);

  @override
  void initState() {
    super.initState();
    _streamSubscription = closeMeStream.listen((shouldClose) { // here we listen for new events coming down the pipe
      setState(() {
        _closeMe = shouldClose; // we got a new "droplet" 
      });
    });
  }

  @override
  void dispose() {
    _streamSubscription.cancel(); // THIS IS QUITE IMPORTANT, we have to close the faucet 
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        SomeWidgetHere(shouldClose: _closeMe), 
        RaisedButton(
          onPressed: () {
            setState(() {
              _closeMe = true;
            });
          },
        )
      ],
    );
  }
}

class SomeWidgetThatUseThePreviousOne extends StatefulWidget { // this one is the faucet, it will emit droplets 
  @override
  _SomeWidgetThatUseThePreviousOneState createState() =>
      _SomeWidgetThatUseThePreviousOneState();
}

class _SomeWidgetThatUseThePreviousOneState
    extends State<SomeWidgetThatUseThePreviousOne> {
  final StreamController<bool> thisStreamWillEmitEvents = StreamController(); // this is the end of the pipe linked to the faucet

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        ThePannel(closeMeStream: thisStreamWillEmitEvents.stream), // we send the other end of the pipe to the cup
        RaisedButton(
          child: Text("THIS SHOULD CLOSE THE PANNEL"),
          onPressed: () {
            thisStreamWillEmitEvents.add(true); // we will emit one droplet here
          },
        ),
        RaisedButton(
          child: Text("THIS SHOULD OPEN THE PANNEL"),
          onPressed: () {
            thisStreamWillEmitEvents.add(false); // we will emit another droplet here
          },
        )
      ],
    );
  }

  @override
  void dispose() {
     thisStreamWillEmitEvents.close(); // close the faucet from this end.
     super.dispose();
  }
}

我希望我的类比可以帮助您了解流概念.

I hope that my analogy will help you understand a bit the streams concept.

这篇关于如何在StatefullWidget中将另一个布尔值更改为另一个?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆