触发功能从小部件到状态对象 [英] Trigger a function from a widget to a State object

查看:74
本文介绍了触发功能从小部件到状态对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是该方案的简化版本:

This is a simplified version of the scenario:

class ParentWdiegt extends StatelessWidget{
//
//
floatinActionButton: FloatingActionButtonWidget(onPressed:()=>CustomWidgetState.someMethod(someValue))
//
//somewhere in the ParentWidget tree
child: CustomWidget() //is stateful
}

CustomWidgetState

CustomWidgetState

class CustomWidgetState extends State<CustomWidget>{
//trigger this function when FAB is pressed in parent widget
someMethod(SomeValue) {//}
}

有什么方法可以公开 someMethod 按下FAB而不使用 InheritedWidget

Is there any way that I can expose someMethod in the state object to be triggered when FAB is pressed without using InheritedWidget?

推荐答案

GlobalKey 允许轻松访问任何小部件的状态;躲开它。
窗口小部件不应与其他窗口小部件直接互动。这是Flutter的核心原则之一。

While GlobalKey allows for an easy access to any widget's state ; avoid it. Widgets should not interact with other widgets directly. This is one of the core principle of Flutter.

Flutter使用了反应式编程。小部件之间通过提交事件进行通信。不是直接编辑所需的小部件。

Flutter uses reactive programming instead. Where widgets communicate with each others by submitting events. Not by directly editing the desired widget.

明显的好处是小部件保持独立。并且可能有数十个小部件可以使用相同的原理相互通信。

The obvious benefit is that widgets stays independant. And potentially dozens of widgets can communicate with each others using the same principle.

我已经举了一个例子此处说明如何使两个不同的小部件共享共同的可编辑值。

I already made an example here on how to make two different widgets share a common editable value.

如果要调用方法,则使用相同的原理:A Listenable Stream 之间共享小部件。但不使用 AnimatedWidget StreamBuilder 进行监听。
相反,我们将手动进行侦听(这需要更多样板)以触发自定义功能。

If you want to call methods instead, this uses the same principle : A Listenable or Stream shared between widgets. But without using AnimatedWidget or StreamBuilder for the listening. Instead we'll do the listening manually (which requires slighly more boilerplate) to trigger a custom function.

以下是使用的示例流

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

class ParentWidget extends StatefulWidget {
  @override
  _ParentWidgetState createState() => _ParentWidgetState();
}

class _ParentWidgetState extends State<ParentWidget> {
  final changeNotifier = new StreamController.broadcast();

  @override
  void dispose() {
    changeNotifier.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return new Column(
      children: <Widget>[
        new AnotherWidget(
          shouldTriggerChange: changeNotifier.stream,
        ),
        new RaisedButton(
          child: new Text("data"),
          onPressed: () => changeNotifier.sink.add(null),
        )
      ],
    );
  }
}

class AnotherWidget extends StatefulWidget {
  final Stream shouldTriggerChange;

  AnotherWidget({@required this.shouldTriggerChange});

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

class _AnotherWidgetState extends State<AnotherWidget> {
  StreamSubscription streamSubscription;

  @override
  initState() {
    super.initState();
    streamSubscription = widget.shouldTriggerChange.listen((_) => someMethod());
  }

  @override
  didUpdateWidget(AnotherWidget old) {
    super.didUpdateWidget(old);
    // in case the stream instance changed, subscribe to the new one
    if (widget.shouldTriggerChange != old.shouldTriggerChange) {
      streamSubscription.cancel();
      streamSubscription = widget.shouldTriggerChange.listen((_) => someMethod());
    }
  }

  @override
  dispose() {
    super.dispose();
    streamSubscription.cancel();
  }

  void someMethod() {
    print('Hello World');
  }

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

在此示例中, someMethod每当单击由<$ c $实例化的 RaisedButton 时,将调用另一个控件 c> _ParentWidgetState 被执行。

In this example, someMethod of AnotherWidget will be called whenever a click on the RaisedButton instantiated by _ParentWidgetState is performed.

这篇关于触发功能从小部件到状态对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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