Flutter:从子部件调用父函数

Flutter: call parent function from child widget

你好,我想从子小部件 (customappbar) 调用一个函数,例如打开抽屉。

有我的代码:

home_page.dart

import 'package:fahrschuleapp/widget/appbar_widget.dart';
import 'package:fahrschuleapp/widget/sidebar_widget.dart';
import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

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

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawerEnableOpenDragGesture: false,
      body: SafeArea(
        child: Center(
          child: Column(
            children: [
              CustomAppBar(
                pFunction: CustomAppBarFunction.menu,
                pContext: context,
                pTitle: 'test',
              ),
            ],
          ),
        ),
      ),
      drawer: SideBar(),
    );
  }
}

我试图用参数“pFunction”来说明应该调用哪个函数 例如 _callFunction

中的导航器弹出或打开菜单等

appbar_widget.dart

import 'package:flutter/material.dart';

enum CustomAppBarFunction {
  menu,
  back,
  exit,
}

class CustomAppBar extends StatelessWidget {
  CustomAppBar({
    Key? key,
    required this.pTitle,
    required this.pContext,
    required this.pFunction,
  }) : super(key: key);

  CustomAppBarFunction pFunction;
  String pTitle;
  BuildContext pContext;

  final List<IconData> _iconList = [
    Icons.menu,
    Icons.arrow_back,
    Icons.close,
  ];

  _callFunction(int index) {
    switch (index) {
      case 0:
        Scaffold.of(pContext).openDrawer();
        break;
      default:
        break;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(
        left: 20,
        right: 20,
      ),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Container(
            margin: const EdgeInsets.all(8),
            child: IconButton(
              onPressed: _callFunction(pFunction.index),
              icon: Icon(
                _iconList[pFunction.index],
              ),
            ),
            decoration: BoxDecoration(
              borderRadius: const BorderRadius.all(Radius.circular(15)),
              color: Theme.of(context).colorScheme.primary,
            ),
          ),
          Container(
            padding: const EdgeInsets.only(left: 15, right: 15),
            child: Text(
              pTitle,
              style: const TextStyle(
                fontFamily: 'Hellix',
                fontSize: 20,
              ),
            ),
          ),
          const SizedBox(
            width: 50.4,
          ),
        ],
      ),
    );
  }
}

我试图在小部件内部调用 _callFunction 但这不起作用 错误输出:

Scaffold.of() called with a context that does not contain a Scaffold.

我该如何解决?或者有更好的方法吗?

Scaffold.of() called with a context that does not contain a Scaffold.

当您尝试从上面没有脚手架的上下文访问脚手架时,会出现此消息。为此,您可以使用 Key。创建一个 GlobalKey 并将其分配给 Scaffold,然后将 Key 传递给 AppBar,从那里您可以访问 Scaffold.

按照下面的代码更改 IconButton,

Builder(builder: (context) {
              return IconButton(
                onPressed:() => _callFunction(pFunction.index, context),
                icon: Icon(
                  _iconList[pFunction.index],
                ),
              ) ;
            })
            

并更改您的 _callFunction,

_callFunction(int index, BuildContext mContext) {
    switch (index) {
      case 0:
        Scaffold.of(mContext).openDrawer();
        break;
      default:
        break;
    }
  }