Flutter: What is BuildContext?
The Flutter BuildContext
holds the location of the widget in the widget tree. The widgets are located and updated in response to state or event changes using the BuildContext by the Flutter framework.
Every widget in Flutter has an BuildContext
associated with it which is passed down from its parent widget. The BuildContext
can be used to retrieve the widget’s location in the widget tree as well as to build its child widgets or to access Flutter’s framework services.
Let us consider an example:
class MyWidget extends StatelessWidget{
@override
Widget build(BuildContext context)
return Container(
child: Text("Hello there 👋"),
);
}
When our widget MyWidget
is built, the context
in the build method becomes the parent of our widget tree. All the child widgets Container
and Text
live under the context of MyWidget
.
If you run the app and press on the “Tap me” text, it gives an error:
The following assertion was thrown while handling a gesture:
Scaffold.of() called with a context that does not contain a Scaffold.
No Scaffold ancestor could be found starting from the context that was passed to Scaffold.of(). This usually happens when the context provided is from the same StatefulWidget as that whose build function actually creates the Scaffold widget being sought.
There are several ways to avoid this problem. The simplest is to use a Builder to get a context that is "under" the Scaffold. For an example of this, please see the documentation for Scaffold.of():
https://api.flutter.dev/flutter/material/Scaffold/of.html
A more efficient solution is to split your build function into several widgets. This introduces a new context from which you can obtain the Scaffold. In this solution, you would have an outer widget that creates the Scaffold populated by instances of your new inner widgets, and then in these inner widgets you would use Scaffold.of().
A less elegant but more expedient solution is assign a GlobalKey to the Scaffold, then use the key.currentState property to obtain the ScaffoldState rather than using the Scaffold.of() function.
The context used was:
MyWidget
at [_displaySnackBar] main.dart:39:24
at <fn> main.dart:28:24
As you can see in the error log
Scaffold.of() called with a context that does not contain a Scaffold.
You might be wondering how can this be. We are passing a context in _displaySnackBar
function so how can we get context error in Scaffold
?
As per our previous conversation:
All the child widgets
Container
andText
live under the context ofMyWidget
.
Since Flutter uses context to look up the tree, when onTap
the function is called, Flutter searches for Scaffold above the Scaffold Widget itself. An error is thrown since there is no Scaffold above it.
The solution is pretty simple, wrap the InkWell
inside a Builder
.
Now, when onTap
is tapped, Flutter takes the context and tries to find the Scaffold in InWell's
parent widget Builder
. This time Builder
contains a parent that has a Scaffold, hence, it works now.
This is a basic example of BuildContext and a trick question asked in Flutter interviews. Comprehending the concept of BuildContext in Flutter is critical, as it constitutes one of the fundamental principles in Flutter development.