繁体   English   中英

Flutter:如何知道我的小部件是否在另一个特定类型的小部件中?

[英]Flutter: How to know if my widget is inside another widget of a specific type?

我正在编写一个名为TopBar的 Widget,与之相关的是另一个名为TopBarAction的 Widget。 我需要知道TopBarAction是否在TopBar内部使用,以便在其构建方法中使用AlignPositioned小部件:

class TopBar extends StatelessWidget {

  final List<Widget> actions;
  final EdgeInsets padding;
  final Alignment actionsAlignment;

  ...

  @override
  Widget build(BuildContext context) {
    final MediaQueryData moc = MediaQuery.of(context);
    return LimitedBox(
      maxWidth: moc.size.width,
      maxHeight: moc.size.height,
      child: Stack(
        alignment: actionsAlignment,
        children: actions,
      ),
    );
  }
}

class TopBarAction extends StatelessWidget {

  final Widget title;
  final VoidCallback onTap;
  final EdgeInsets? padding;
  final Alignment? actionAlignment;

  ...

  @override
  Widget build(BuildContext context) {
    bool isParentTopBar = false;
    context.visitAncestorElements((element) { <-------- Is this the right way to do it??
      if (element.widget is TopBar) {
        isParentTopBar = true;
      }
      return false; // return false to stop visiting other widgets. Only visit the direct parent.
    });
    late Widget child;
    child = Padding(
      padding: padding ?? EdgeInsets.zero,
      child: InkWell(
        onTap: onTap,
        child: title,
      ),
    );
    if (actionAlignment != null && isParentTopBar) {
      child = Align(
        alignment: actionAlignment!,
        child: child,
      );
    }
    return child;
  }
}

visitAncestorElements可能会变得非常昂贵,但在您的情况下,您只是添加对父节点的额外访问,这可能没问题。

但我建议以下内容来简化您的代码并防止使用visitAncestorElements


class TopBar extends StatelessWidget {
  const TopBar({
    required this.actions,
    required this.padding,
    required this.actionsAlignment,
    super.key,
  });

  final List<Widget> actions;
  final EdgeInsets padding;
  final Alignment actionsAlignment;

  @override
  Widget build(BuildContext context) {
    final moc = MediaQuery.of(context);
    return LimitedBox(
      maxWidth: moc.size.width,
      maxHeight: moc.size.height,
      child: Stack(
        alignment: actionsAlignment,
        children: [
          for (final a in actions)
            if (a is TopBarAction)
              Align(
                alignment: actionsAlignment,
                child: a,
              )
            else
              Padding(padding: padding, child: a)
        ],
      ),
    );
  }
}

class TopBarAction extends StatelessWidget {
  const TopBarAction({
    required this.title,
    required this.onTap,
    super.key,
  });

  final Widget title;
  final VoidCallback onTap;

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: onTap,
      child: title,
    );
  }
}

让我知道我是否了解您的需求。

暂无
暂无

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

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