代码之家  ›  专栏  ›  技术社区  ›  Shady Aziza

将函数从小部件触发到状态对象

  •  6
  • Shady Aziza  · 技术社区  · 8 年前

    这是场景的简化版本:

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

    自定义WidgetState

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

    我有什么办法可以揭露 someMethod 当按下fab而不使用 InheritedWidget ?

    2 回复  |  直到 8 年前
        1
  •  20
  •   Benno Richters    7 年前

    同时 GlobalKey 允许轻松访问任何小部件的状态;避免访问。 小部件应该 直接与其他小部件交互。这是颤振的核心原理之一。

    颤振使用反应式编程代替。其中小部件通过提交事件相互通信。不是直接编辑所需的小部件。

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

    我已经做了一个例子 here 关于如何使两个不同的小部件共享一个公共的可编辑值。

    如果您想改为调用方法,则使用相同的原则:a Listenable Stream 在小部件之间共享。但不用 AnimatedWidget StreamBuilder 为了倾听。 相反,我们将手动进行监听(这需要更多的样板文件)来触发一个自定义函数。

    下面是一个使用 河流

    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 属于 AnotherWidget 将在每次单击 RaisedButton 实例化者 _ParentWidgetState 执行。

        2
  •  2
  •   Günter Zöchbauer    8 年前

    你可以使用 GlobalKey 为此:

    // some global place
    final customWidgetKey = new GlobalKey<CustomWidgetState>();
    

      // import the file with "customWidgetKey"
    
      new CustomWidget(key: customWidetKey, ...)
    

      // import the file with "customWidgetKey"
    
      floatinActionButton: FloatingActionButtonWidget(
          onPressed: ()=>customWidgetKey.currentState.someMethod(someValue))
    
        3
  •  -1
  •   Taosif7    6 年前

    尝试存储小部件的状态,然后访问

    class MySFWidget extends StatefulWidget {
      SFWidgetState currState;
    
      @override
      SFWidgetState createState(){
        currState = new SFWidgetState();
        return currState;
      };
    
    }
    
    class SFWidgetState extends State<MySFWidget> {
    
      int prop;
    
      void SomeMethod(){
        // DO Something
      }
    
      @override
      Widget build(BuildContext context) {
        return null;
      }
    
    }
    

    然后,通过以下方式访问其属性或调用方法:

    myWidgetInstance.currState.prop

    myWidgetInstance.currState.SomeMethod()