I am writing a Widget called TopBar
, and associated with it is another Widget called TopBarAction
. I need to know if TopBarAction
is being used inside TopBar
or not in order to use an Align
or Positioned
widget in its build method:
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
may get very expensive but in your case you're just adding an additional visit to the parent node, and that might be ok.
But I'd suggest the following to simplify your code and to prevent the use of 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,
);
}
}
Let me know if i've understood what you need.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.