BuildContext는 Widget Tree상 Widget의 위치 정보를 담고 있는 Object이다.
그럼 Widget Tree상 Widget의 위치 정보를 알아서 우리는 무엇을 할 수 있을까?
지정된 context의 Theme 정보는 가져올 수 있다.
Theme.of(context).primaryColor
Theme.of(context).textTheme.bodySmall
Dialog 를 보여줄 때 사용.
showDialog(
context: context,
builder: (_) {
return AlertDialog(
title: Text('Dialog test'),
);
},
);
SnackBar를 보여줄때 사용
Scaffold.of(context).showSnackBar(SnackBar(content: Text('SnackBar Text')));
SnackBar 의 경우 Scaffold.of(context) 를 통해 Context에 접근한다.
이때 context 사용에 유의해야한다. 아래는 잘못 Scaffold.of(context) 사용했을 때와 올바르게 사용하는 방법이다.
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) { // ===A=== 해당 Context는 MyHomePage의 Context 입니다. 아래 Scaffold 의 Context를 포함하고 있지 않습니다.
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// 에러가 나는 플랫버튼
// 아래 Scaffold.of(context) 뜻은 위젯 트리상 가장 가까운 Scaffold 위젯의 context를 찾아서 반환해줘 라는 뜻이다.
// 하지만 A 부분을 보면 MyHomePage에서 떨어진 Context만을 명시해 놓았다.
// 즉 A 부분을 아래부터 사용된 위젯들의 Context는 각자 자신의 Conttext를 알지 못한다.
// 그렇기에 에러가 발생한다.
FlatButton(
onPressed: () {
Scaffold.of(context).showSnackBar(SnackBar(content: Text('에러')));
},
child: Text('에러!'),
),
// 정상 작동하는 플랫버튼
// Builder 를 통해 context를 명시하여 현재 Builder의 부모가 되는 위젯들의 Context를 인지할 수 있다.
// Scaffold 역시 부모 위젯중 하나이기 때문에 에러가 나지 않고 정상 작동된다.
Builder(builder: (context) {
return FlatButton(
onPressed: () {
Scaffold.of(context)
.showSnackBar(SnackBar(content: Text('안녕')));
},
child: Text('눌러주세요!'));
}),
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
context를 이해하는 가장 빠르 방법은 context를 어디서 어떻게 사용되는지를 직접 경험해보는게 제일 빠른것 같다.