简体   繁体   English

如何从另一个有状态小部件调用有状态小部件中的函数?

[英]How to call a function in a Stateful Widget from another StatefulWidget?

Hello I want to call the function that are inside the StatefulWidget of the formCliente class to clean the controllers.but I want to access it via a button that is inside the StatefulWidget of the formFinanceiro class.您好,我想调用 formCliente 类的 StatefulWidget 内的函数来清理控制器。但我想通过 formFinanceiro 类的 StatefulWidget 内的按钮访问它。 help me please!请帮帮我! thanks.谢谢。

      class _CadastrarClienteState extends State<CadastrarCliente>
with TickerProviderStateMixin {     
    body: Form(
      key: formkey,
      child: TabBarView(
        physics: physics, //NeverScrollableScrollPhysics()
        controller: _tabController,
        children: [
          FormCliente(),
          FormDocumento(),
          FormVeiculo(),
          FormContrato(),
          FutureBuilder(
              future: getTrabalhaComCota(),
              builder: (context, snapshot) {
                if (snapshot.hasData && !snapshot.hasError) {
                  //   print(' chamada cota:${snapshot.data}');
                  return FormFinanceiro(
                      itemsCota: snapshot.data, formKey: formkey);
                } else {
                  return Center(
                    child: CircularProgressIndicator(),
                  );
                }
              }),
        ],
      ),
    ),

} ] ]]

You can use Streams to achive the same, please see the code below :您可以使用 Streams 来实现相同的效果,请参阅下面的代码:

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

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(title: Text("Demo")),
        body: MyApps(),
      ),
    );
  }
}

class MyApps extends StatefulWidget {
  @override
  _MyAppsState createState() => _MyAppsState();
}

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

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

  buttonClicked() => changeNotifier.sink.add(null);

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        FormCliente(
          shouldTriggerChange: changeNotifier.stream,
        ),
        FormFinanceiro(buttonClicked: buttonClicked),
      ],
    );
  }
}

class FormCliente extends StatefulWidget {
  final Stream shouldTriggerChange;

  FormCliente({this.shouldTriggerChange});

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

class _FormClienteState extends State<FormCliente> {
  StreamSubscription streamSubscription;

  @override
  initState() {
    super.initState();
    if (widget.shouldTriggerChange != null) {
      streamSubscription =
          widget.shouldTriggerChange.listen((_) => clearYourFormMethod());
    }
  }

  @override
  didUpdateWidget(FormCliente old) {
    super.didUpdateWidget(old);
    if (widget.shouldTriggerChange != old.shouldTriggerChange) {
      streamSubscription.cancel();
      streamSubscription =
          widget.shouldTriggerChange.listen((_) => clearYourFormMethod());
    }
  }

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

  void clearYourFormMethod() {
    print('Please clear your form here');
  }

  @override
  Widget build(BuildContext context) {
    return Text("FormCliente");
  }
}

class FormFinanceiro extends StatefulWidget {
  final Function buttonClicked;

  FormFinanceiro({this.buttonClicked});

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

class _FormFinanceiroState extends State<FormFinanceiro> {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        RaisedButton(
          child: new Text("FormFinanceiro"),
          onPressed: widget.buttonClicked,
        )
      ],
    );
  }
}

You need to lift the state up:您需要提升state

  1. Create the controller in _CadastrarClienteState class._CadastrarClienteState类中创建控制器。
  2. Create a callback in _CadastrarClienteState_CadastrarClienteState创建回调
  3. Pass the controller to the child FormFinanceiro .将控制器传递给子FormFinanceiro
  4. Pass the callback to the child FormCliente .将回调传递给子FormCliente
  5. Now, modify your onbuttonpressed function in FormCliente such that the callback is called when the button is pressed.现在,修改你的onbuttonpressed功能FormCliente使得按下按钮时调用回调。
  6. Finally in the callback method present in _CadastrarClienteState , clear the values using controllers.最后,在_CadastrarClienteState中的回调方法中,使用控制器清除值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM