debugCheckHasMaterial function
Asserts that the given context has a Material ancestor.
Used by many material design widgets to make sure that they are only used in contexts where they can print ink onto some material.
To call this function, use the following pattern, typically in the relevant Widget's build method:
assert(debugCheckHasMaterial(context));
Does nothing if asserts are disabled. Always returns true.
Implementation
bool debugCheckHasMaterial(BuildContext context) {
assert(() {
if (context.widget is! Material && context.ancestorWidgetOfExactType(Material) == null) {
final StringBuffer message = StringBuffer();
message.writeln('No Material widget found.');
message.writeln(
'${context.widget.runtimeType} widgets require a Material '
'widget ancestor.'
);
message.writeln(
'In material design, most widgets are conceptually "printed" on '
'a sheet of material. In Flutter\'s material library, that '
'material is represented by the Material widget. It is the '
'Material widget that renders ink splashes, for instance. '
'Because of this, many material library widgets require that '
'there be a Material widget in the tree above them.'
);
message.writeln(
'To introduce a Material widget, you can either directly '
'include one, or use a widget that contains Material itself, '
'such as a Card, Dialog, Drawer, or Scaffold.'
);
message.writeln(
'The specific widget that could not find a Material ancestor was:'
);
message.writeln(' ${context.widget}');
final List<Widget> ancestors = <Widget>[];
context.visitAncestorElements((Element element) {
ancestors.add(element.widget);
return true;
});
if (ancestors.isNotEmpty) {
message.write('The ancestors of this widget were:');
for (Widget ancestor in ancestors)
message.write('\n $ancestor');
} else {
message.writeln(
'This widget is the root of the tree, so it has no '
'ancestors, let alone a "Material" ancestor.'
);
}
throw FlutterError(message.toString());
}
return true;
}());
return true;
}