【问题标题】:Flutter: calling child class function from parent class of onother fileFlutter:从另一个文件的父类调用子类函数
【发布时间】:2026-01-07 00:35:01
【问题描述】:

问题: 如何从 IconButton 的 onPressed() 调用 methodA()。 我试图通过使用 GlobalKey 来做到这一点: GlobalKey<_mybuttonstate> globalKey = GlobalKey(); 但它返回一个错误。

我已经阅读了很多关于此的论坛,并且我尝试了所有提出的解决方案,但没有一个对我有用。

代码:

ma​​in.dart

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

void main() {
  runApp(MaterialApp( title: 'My app', home: MyApp(),));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          leading: IconButton(
            icon: Icon(Icons.help),
            onPressed: () {
              // how can I call methodA from here?
            },
          ),
        ),
        body: HomePage(),
      ),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: MyButton(),
    );
  }
}

button.dart

import 'package:flutter/material.dart';

class MyButton extends StatefulWidget {
  @override
  _MyButtonState createState() => _MyButtonState();
}

class _MyButtonState extends State<MyButton> {

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

  void methodA(){
    print('methodA');
  }

}

我已经阅读了很多关于此的论坛,并且我尝试了所有提出的解决方案,但没有一个对我有用。

【问题讨论】:

  • 您在 button.dart 中使用有状态小部件是否有特殊原因?
  • 如果当您按下 MyButton 时,尝试发送一个标志(触发器),例如 true 或 false。因此,如果您的 initstate 为 true,请运行您的方法 A。

标签: class flutter dart widget setstate


【解决方案1】:

首先,您必须将文件作为package 导入main.dart

Main.dart:(只是写了导入文件的方式)

import 'package:prioject_name/file_name.dart';

注意:这是针对lib 目录下的文件。 如果您的文件位于 lib 内的不同目录下 然后相应地添加路径,

例如:Button.dart 位于 lib 文件夹内的 widgets 文件夹中:

lib
|____widgets
     |____Button.dart

那么导入语句如下:

import 'package:prioject_name/widgets/Button.dart';

然后尝试你的全局键方法来调用函数:


如果还是不行可以用我的方法 我如何在onPressedonTapped 中调用来自不同class 的方法:

您的 Button.dart 文件。

import 'package:flutter/material.dart';

// changed the method definition class
class MyButton extends StatefulWidget {
void methodA(){
    print('methodA');
  }
  @override
  _MyButtonState createState() => _MyButtonState();
}

class _MyButtonState extends State<MyButton> {

  @override
  Widget build(BuildContext context) {
  ...
  widget.methodA(); // this would call the method A, anywhere inside the Widget build() function.
    return Container( );
  }
  

}

现在在 Main.dart:

import 'package:prioject_name/Button.dart';

//call the function here using className().functioName();
....
onPressed(){
  MyButton().methodA();
}

【讨论】:

    【解决方案2】:

    看看InheritedWidget 课程(并观看视频)。

    小部件的基类,可有效地向下传播信息 树。

    您可以查看创建一个包含ValueNotifierInheritedWidget

    class MyInheritedWidget extends InheritedWidget {
      
      final ValueNotifier<int> buttonTapCountNotifier;
    
      const MyInheritedWidget({
        Key key,
        @required this.buttonTapCountNotifier,
        @required Widget child,
      })  : assert(child != null),
            super(key: key, child: child);
    
      static MyInheritedWidget of(BuildContext context) {
        return context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>();
      }
    
    }
    

    您的MyButton 类可以调用MyInheritedWidget.of(context).buttonTapCountNotifier 来获取ValueNotifier 并向其添加监听器。
    每次ValueNotifier 通知您的MyButton 类该值已增加时,您可以执行methodA

    【讨论】:

      【解决方案3】:

      您可以使用 Provider 包,这是在 Flutter 应用程序中管理状态的首选方法。这也将帮助您以一种巧妙的方式组织和发展应用程序。

      看看下面的工作代码。

      1. 定义一个 ChangeNotifier (PressedProvider) 将保存 应用在唯一位置的当前状态以及 onPress 函数的行为
      2. 你包装你的应用程序 使用 ChangeNotifierProvider 小部件
      3. 你包装接收 带有 Consumer 的小部件
      4. 当你得到 Provider.of() 需要做某事并在其上调用方法
      5. 它将通知消费者发生变化

      代码:

      import 'package:flutter/material.dart';
      import 'package:provider/provider.dart';
      
      final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
      
      void main() {
        runApp(ChangeNotifierProvider<PressedProvider>( // 2
          create: (_) => PressedProvider(),
          child: MyApp(),
        ));
      }
      
      class PressedProvider extends ChangeNotifier { // 1
        void pressButton() {
          print("pressButton");
          notifyListeners();
        }
      }
      
      class MyApp extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return MaterialApp(
            theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
            debugShowCheckedModeBanner: false,
            home: Scaffold(
              appBar: AppBar(
                leading: Consumer<PressedProvider>( // 3
                  builder: (_, provider, widget) => IconButton(
                    icon: Icon(Icons.help),
                    onPressed: () {
                      provider.pressButton();
                    },
                  ),
                ),
              ),
              body: Center(
                child: MyButton(),
              ),
            ),
          );
        }
      }
      
      class MyButton extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          PressedProvider provider = Provider.of<PressedProvider>(context); // 4
          return Center(
            child: RawMaterialButton(
                child: Text("Press me"),
                onPressed: () => provider.pressButton()),
          );
        }
      }
      

      【讨论】:

        最近更新 更多