Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从另一个有状态小部件调用一个有状态小部件中的方法-Flutter_Flutter_Dart - Fatal编程技术网

从另一个有状态小部件调用一个有状态小部件中的方法-Flutter

从另一个有状态小部件调用一个有状态小部件中的方法-Flutter,flutter,dart,Flutter,Dart,我有一个颤振项目,我正在工作,我不能把整个代码,因为它超过500行的代码,所以我会尽量问我的问题,因为我使用的imp.部分的代码简单 我有一个有状态的小部件,在扩展State 文件lib\main.dart 只需要一个简单的函数,比如 class MyAppState extends State<MyApp>{ ... void printSample (){ print("Sample text"); } ... 要调用父函数,可以使用回调模式。在本例中,函数(onColor

我有一个颤振项目,我正在工作,我不能把整个代码,因为它超过500行的代码,所以我会尽量问我的问题,因为我使用的imp.部分的代码简单

我有一个有状态的小部件,在扩展
State

文件
lib\main.dart

只需要一个简单的函数,比如

class MyAppState extends State<MyApp>{
...
void printSample (){
  print("Sample text");
}
...

要调用父函数,可以使用回调模式。在本例中,函数(
onColorSelected
)被传递给子级。按下按钮时,孩子调用该函数:

import 'package:flutter/material.dart';

class Parent extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return ParentState();
  }
}

class ParentState extends State<Parent> {
  Color selectedColor = Colors.grey;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Container(
          color: selectedColor,
          height: 200.0,
        ),
        ColorPicker(
          onColorSelect: (Color color) {
            setState(() {
              selectedColor = color;
            });
          },
        )
      ],
    );
  }
}

class ColorPicker extends StatelessWidget {
  const ColorPicker({this.onColorSelect});

  final ColorCallback onColorSelect;

  @override
  Widget build(BuildContext context) {
    return Row(
      children: <Widget>[
        RaisedButton(
          child: Text('red'),
          color: Colors.red,
          onPressed: () {
            onColorSelect(Colors.red);
          },
        ),
        RaisedButton(
          child: Text('green'),
          color: Colors.green,
          onPressed: () {
            onColorSelect(Colors.green);
          },
        ),
        RaisedButton(
          child: Text('blue'),
          color: Colors.blue,
          onPressed: () {
            onColorSelect(Colors.blue);
          },
        )
      ],
    );
  }
}

typedef ColorCallback = void Function(Color color);


在flatter中,不鼓励从父窗口小部件调用子窗口小部件的方法。相反,flatter鼓励您将子对象的状态作为构造函数参数传递。您只需在父窗口小部件中调用
setState
,而不是调用子窗口的方法来更新其子窗口


另一种方法是颤振中的
控制器
类(
滚动控制器
动画控制器
,…)。这些参数也作为构造函数参数传递给子级,它们包含控制子级状态的方法,而无需在父级上调用
setState
。例如:

scrollController.animateTo(200.0, duration: Duration(seconds: 1), curve: Curves.easeInOut);
然后,要求子级侦听这些更改以更新其内部状态。当然,您也可以实现自己的控制器类。如果需要,我建议您查看flatter的源代码,了解它是如何工作的


未来和流是传递状态的另一种替代方法,也可用于调用子函数


但我真的不推荐。如果您需要调用子小部件的方法,则很可能您的应用程序架构有缺陷尝试将状态向上移动到共同祖先

我通过反复试验找到了另一种解决方案,但它奏效了

import 'main.dart' as main;
然后将这一行添加到onPressed下

main.MyAppState().printSample();

如果要调用printSample()func,可以使用:

class Myapp extends StatefulWidget{
...
    MyappState myAppState=new MyappState();
    @override
    MyappState createState() => myAppState;
    void printSample(){
        myAppState.printSample();
    }
}
class MyAppState extends State<MyApp>{
    void printSample (){
        print("Sample text");
    }
}

...............
Myapp _myapp = new Myapp();
myapp.printSample();
...
类Myapp扩展StatefulWidget{
...
MyappState MyappState=新的MyappState();
@凌驾
MyappState createState()=>MyappState;
void printSample(){
myAppState.printSample();
}
}
类MyAppState扩展了状态{
无效打印样本(){
打印(“样本文本”);
}
}
...............
Myapp _Myapp=新的Myapp();
myapp.printSample();
...

您可以尝试一下,它将从
Page1
StatefulWidget
)小部件调用
Page2
StatefulWidget
)中定义的方法

class Page1扩展了StatefulWidget{
@凌驾
_Page1State createState();
}
类_Page1State扩展状态{
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:中(
孩子:升起按钮(
子项:文本(“调用第2页方法”),
onPressed:()=>Page2().method(),
),
),
);
}
}
类Page2扩展了StatefulWidget{
方法()=>createState().methodInPage2();
@凌驾
_Page2State createState();
}
类_Page2State扩展状态{
methodInPage2()=>打印(“第2页中的方法”);
@凌驾
小部件构建(BuildContext上下文)=>Container();
}

您可以通过使用widget的键来实现

myWidget.dart

    class MyWidget extends StatefulWidget {
     
      const MyWidget ({Key key}) : super(key: key);
     
      @override
      State<StatefulWidget> createState()=> MyState();
    
  
    }

   class MyState extends State<MyWidget >{
        
          
               
      Widget build(BuildContext context){ return ....}
    
      void printSample (){
         print("Sample text");
      }
        
 }
通过该键,您可以调用状态内的任何公共方法

_myKey.currentState.printSample();

这里主页是父页面,子页面是子页面。有一个名为onSelectItem的方法,我们需要从子页面调用它

class HomePage extends StatefulWidget {

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

class HomePageState extends State<HomePage> {

  onSelectItem(String param) {
    print(param);
  }

  @override Widget build(BuildContext context) {

  }
}

class ChildPage extends StatefulWidget {
  final HomePageState homePageState;

  ChildPage({Key key, @required this.homePageState}) : super(key: key);

  _ChildPageState createState() => _ChildPageState();
}

class _ChildPageState extends State<ChildPage> {
  @override Widget build(BuildContext context) {

    return RaisedButton(
      onPressed: () {
        widget.homePageState.onSelectItem("test");
      },
      child: const Text(
          'Click here',
          style: TextStyle(fontSize: 20)
      ),
    );
  }
}
类主页扩展StatefulWidget{
@覆盖HomePageState createState()=>HomePageState();
}
类HomePageState扩展了状态{
onSelectItem(字符串参数){
打印(参数);
}
@覆盖小部件构建(构建上下文){
}
}
类ChildPage扩展StatefulWidget{
最终主页状态主页状态;
ChildPage({Key Key,@required this.homePageState}):超级(Key:Key);
_ChildPageState createState()=>\u ChildPageState();
}
类_ChildPageState扩展状态{
@覆盖小部件构建(构建上下文){
返回上升按钮(
已按下:(){
widget.homePageState.onSelectItem(“测试”);
},
子:常量文本(
“单击此处”,
样式:文本样式(字体大小:20)
),
);
}
}

因此,通过使用小部件父类状态我们可以调用父类方法。

显然,您只需创建一个只包含一个方法的文件,就可以直接调用它

例如,我想在名为
custom\u show\u bottom\u sheet.dart的文件中创建一个showModalBottomSheet方法:

import 'package:flutter/material.dart';

customShowBottomSheet(context, Widget child){
    showModalBottomSheet(
      isScrollControlled: true,
      context: context,
      builder: (BuildContext context) {
        return Wrap(
          children: <Widget>[
            child,
          ],
        );
      });
}
希望这是一个帮助!如果我误解了你的问题或其他什么,请告诉我。

在使用回调时,对于简单的用例来说,'s很好,对于更复杂的设置,它们可能应该被视为反模式,因为它们与小部件类型挂钩,并且依赖于低级实现逻辑

如果您发现自己添加了越来越多的回调/globalkey,并且开始变得混乱,那么可能是时候切换到+。通过这种方式,您可以将事件与特定的小部件类型分离,并抽象出小部件间的通信逻辑

注册一个事件控制器 在顶级小部件(应用程序级或页面级,取决于您的需要)中创建
StreamController
实例,并确保在
dispose()
方法中释放它:

class\u TopLevelPageState扩展状态{
StreamController eventController=StreamController.broadcast();
// ...
@凌驾
无效处置(){
eventController.close();
super.dispose();
}
}
eventController
实例作为构造函数参数向下传递到
  GlobalKey<MyState> _myKey = GlobalKey();
MyWidget(
key : _myKey,
)
_myKey.currentState.printSample();
class HomePage extends StatefulWidget {

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

class HomePageState extends State<HomePage> {

  onSelectItem(String param) {
    print(param);
  }

  @override Widget build(BuildContext context) {

  }
}

class ChildPage extends StatefulWidget {
  final HomePageState homePageState;

  ChildPage({Key key, @required this.homePageState}) : super(key: key);

  _ChildPageState createState() => _ChildPageState();
}

class _ChildPageState extends State<ChildPage> {
  @override Widget build(BuildContext context) {

    return RaisedButton(
      onPressed: () {
        widget.homePageState.onSelectItem("test");
      },
      child: const Text(
          'Click here',
          style: TextStyle(fontSize: 20)
      ),
    );
  }
}
import 'package:flutter/material.dart';

customShowBottomSheet(context, Widget child){
    showModalBottomSheet(
      isScrollControlled: true,
      context: context,
      builder: (BuildContext context) {
        return Wrap(
          children: <Widget>[
            child,
          ],
        );
      });
}
import 'package:flutter/material.dart';
import '../custom_show_bottom_sheet.dart';

class TestScreen extends StatelessWidget {
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: FloatingActionButton(
            onPressed: (){
              customShowBottomSheet( //A method is called here
                  context,
                  Container(
                    height: 200,
                    child: Text("This is a test"),
                  )
              );
            }),
      ),
    );
  }
}