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

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

问题描述

这是场景的简化版本:

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

自定义控件状态

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

有什么方法可以在不使用 InheritedWidget 的情况下,在按下 FAB 时在要触发的状态对象中公开 someMethod 吗?

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.

如果你想调用方法,这使用相同的原则:在小部件之间共享的 ListenableStream.但不使用 AnimatedWidgetStreamBuilder 进行监听.相反,我们将手动进行监听(这需要更多样板文件)以触发自定义函数.

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.

这是一个使用 Stream 的例子.

Here's an example using Stream.

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();
  }
}

在这个例子中,每当点击 _ParentWidgetState 实例化的 RaisedButton 时,都会调用 AnotherWidgetsomeMethod被执行.

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

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

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